這是一個動態規劃問題,海峽前沿實現具有太多數據依賴性,無法用於SIMD計算。
但是,如果將算法從逐行迭代更改爲對角線迭代,則可以並行計算整個對角線。見下圖。
下面的「僞」的代碼使用與1個額外行/列的矩陣中,爲了簡化的「內部」的計算。這個額外的行/列在每次對角線迭代之前被初始化。
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指令進行計算,或者只知道如何並行化/向量化計算。
當你說「SIMD」時,你需要指定你在說什麼CPU系列,例如, x86(在這種情況下,您需要指定可以假定的SSE/AVX級別),PowerPC(AltiVec),POWER(VMX/VSX),ARM(氖燈),Cell等。 –
此外,什麼是數據類型'refSeq []','otherSeq []'和'L [] []'? –
你確實很持久地使這個最長的子串算法並行:)再次 - 數據依賴。 SIMD在獨立的數據塊上工作。在這裏你有循環內部的if(壞)和if(更壞)。你需要重新設計算法來使用掩碼而不是分支,我不確定它是否會運行得更快。 –