リテラル(p(a、b)、q(c、d)、r(a、d)など)を含むデータセットに対してクエリを実行するには、 ···)。リテラルはMap<String, Queue<Literal>>
のデータ構造体に格納され、keyは述語(p、q、rなど)およびリテラルのArrayDequeueです。このメソッドはバックトラッキングアルゴリズム内で実行され、 u(x、z): - p(x、y)、q(y、z)のようなルールのインスタンス化を検索します。Javaでクエリを取得する方法の並列化の問題
以下のメソッドは、バックトラッキングアルゴリズム内で何度も実行され、クエリパラメータ(例えば、teta = {(x = a)、y = b)} &述語= qと一致するリテラルを探すために、アリティ= 2)。 私は多くのルールを持っており、各ルールのインスタンス化はスレッドによって実行されます(私はExecutorServiceを使用してスレッドプールを使用しています)。次の方法は私のHotSpotです。しかし、私は希望のスピードアップを達成することができません(4スレッドを実行すると2回のみ)。 CPUの動作をシミュレートするために、メソッドでThread.Sleep(1)を追加し、予想されるスピードアップ(3.9)を達成しました!データの局所性やキャッシュミスに問題がありますか?次の構造体キャッシュは十分にフレンドリーですか?
オブジェクトの割当率は13バイト/秒ですが、私は1.8 JDKの4つのCPUコアと4つのスレッドを実行する4つのCPUコアを持つマシンでアプリケーションを実行しています。
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);
}
ご協力いただきありがとうございます。
ループを実行する前にすべての位置を解析してください(分離して保存する)。 – Nadir
@ Nadir:位置を解析することはどういう意味ですか? – nasim
実際のループの前に、このすべての計算を実行してください。 – Nadir