これはダイナミックプログラミングの問題であり、ストレートフォワード実装ではSIMD計算に適したデータ依存性があります。
ただし、アルゴリズムを行ごとに反復して対角に反復するように変更すると、対角線全体を並列に計算できます。下の画像を参照してください。
以下「擬似」コードが「内側」の計算を簡単にするために1余分な行/列を有する行列を使用します。この余分な行/列はすべての対角反復の前に初期化されます。あなたは計算のために、実際のSIMD命令を望んでいた、または単に/並列計算をベクトル化する方法を知っていれば
int i, j, k;
for (k = 1; ; k++) {
int minI = k > refLen ? k - refLen : 1;
int maxI = k > otherLen ? otherLen : k - 1;
for (i = maxI; i >= minI;) {
j = k - i;
// vectorized calculation 256 bit (AVX2)
if (i >= 32 && otherLen - j >= 32) {
// calculate 32 values of the diagonal with SIMD
i -= 32;
continue;
}
// vectorized calculation 128 bit (SSE)
if (i >= 16 && otherLen - j >= 16) {
// calculate 16 values of the diagonal with SIMD
i -= 16;
continue;
}
// scalar calculation
if (refSeq[i - 1] == otherSeq[j - 1]) {
L[i][j] = L[i - 1][j - 1] + 1;
} else {
L[i][j] = 0;
}
i--;
}
if (k == otherLen + refLen) {
break;
}
// initialize next j-endpoint in diagonal
if (k <= refLen) {
L[0][k] = 0;
}
// initialize next i-endpoint in diagonal
if (k <= otherLen) {
L[k][0] = 0;
}
}
わかりません。
「SIMD」と言ったときに話しているCPUファミリを指定する必要があります。 x86(この場合、想定できるレベルのSSE/AVXを指定する必要があります)、PowerPC(AltiVec)、POWER(VMX/VSX)、ARM(Neon)、Cellなど –
また、 'refSeq []'、 'otherSeq []'、 'L [] []'? –
あなたは、この最長の部分文字列アルゴリズムを並列にすることは確かに永続しています:)もう一度 - データ依存。 SIMDは独立したデータブロックで動作します。ここでは、ループ内に 'if'(悪い)と' if'があります(さらに悪い)。分岐の代わりにマスキングを採用するようにアルゴリズムを再設計する必要があり、高速化するかどうかは分かりません。 –