我有以下方法来对包含文字的数据集执行查询(例如 p(a,b),q(c,d),r(a,d) . . .)。文字存储在Map<String, Queue<Literal>>
中数据结构,其中 key 是它们的谓词(例如 p、q、r...)和 Literals 的 ArrayDequeue。此方法在回溯算法中执行,以查找规则的实例化,例如:
u(x,z) :- p(x,y), q(y,z)。
以下方法在回溯算法中执行多次,并尝试查找与查询参数匹配的文字(例如 teta={(x=a),(y=b)} & predicate=q, arity =2)。 我有很多规则,每个规则实例化都是由一个线程完成的(我使用 ExecutorService 来使用线程池)。下面的方法是我的HotSpot。但是,我无法实现所需的加速(运行四个线程时仅加速 2 倍)。为了模拟 CPU 工作,我在方法中添加了 Thread.Sleep(1),然后实现了预期的加速 (3.9)!我是否存在数据局部性或缓存未命中问题?我的以下结构缓存是否足够友好?
此外,我的对象分配率为 13 字节/秒,并且我在具有 4 个 CPU 核心、1.8 JDK 并运行 4 个线程的机器上运行该应用程序。
private void indexFactsWithJointVars(String[][] teta, String predicate, int arity){
Map<String, Queue<Literal>>
indexedFactsWithJointVars = new HashMap<>();
// indexedFactsWithAllFreeVars also has Map<String, Queue<Literal>> data structure
Queue<Literal> literals = indexedFactsWithAllFreeVars.get(predicate);
Queue<Literal> matchedLiterals = new ArrayDeque<>();
for (Literal edb_lit: literals){
boolean match = true;
for (int i=0; i<teta.length; i++){
int position = Integer.parseInt(teta[i][0]);
String attribute = teta[i][1];
if (!edb_lit.getPredicate(position).equals(attribute)){
match = false;
break;
}
}
if (match)
matchedLiterals.add(edb_lit);
}
indexedFactsWithJointVars.put(predicate, matchedLiterals);
}
预先感谢您的帮助!
最佳答案
该问题可能是线程共享数据的争用。当您在线程中模拟本地工作时,相对性能会提高,这一事实与此一致,因为暂停模拟工作实际上不会访问任何共享对象或资源。
您的代码片段没有提供足够的信息来确定其他详细信息,但 indexedFactsWithAllFreeVars
可能是正在争用的资源,因为如果在线程之间共享,则很可能,并且应该是同步访问。但是,考虑到模拟工作的结果,如果线程中实际上要执行实际工作,并且只要该实际工作不争夺共享资源,您就可以在实际情况下获得预期的加速,所以这可能不是一个真正的问题..
关于java - java中获取查询的方法的并行加速问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36824486/