1
我做了一些嘗試在cuda中實現rc4密碼算法的高效。我使用共享內存來存儲內部排列狀態,照顧分區內存佈局,以便在變形中使用並行線程訪問來處理時間。我還試圖通過使用'i'索引的讀/寫訪問是連續的並且可以打包成32位字的事實來最小化訪問次數。最後,我利用常量內存來初始化排列狀態。即使考慮到主機和GPU之間的暢通通信可以用於實現最佳報告實現(例如參見guapdf cracker)的吞吐量,我預計只能獲得大約50%的吞吐量部分覆蓋計算。我不明白爲什麼,我正在尋找新的改進想法或對我可能做出的錯誤假設的評論。用cuda優化rc4
這裏是我的KSA(密鑰設置)內核的一個玩具實現,其中一個密鑰減少到4個字節。
__constant__ unsigned int c_init[256*32/4];
__global__ void rc4Block(unsigned int *d_out, unsigned int *d_in)
{
__shared__ unsigned int s_data[256*32/4];
int inOffset = blockDim.x * blockIdx.x;
int in = inOffset + threadIdx.x;
unsigned int key, u;
// initialization
key = d_in[in];
for(int i=0; i<(256/4); i++) { // read from constant memory
s_data[i*32+threadIdx.x] = c_init[i*32+threadIdx.x];
}
// key mixing
unsigned char j = 0;
unsigned char k0 = key & 0xFF;
unsigned char k1 = (key >> 8) & 0xFF;
unsigned char k2 = (key >> 8) & 0xFF;
unsigned char k3 = (key >> 8) & 0xFF;
for(int i=0; i<256; i+=4) { // unrolled
unsigned int u, sj, v;
unsigned int si = s_data[(i/4)*32+threadIdx.x];
unsigned int shiftj;
u = si & 0xff;
j = (j + k0 + u) & 0xFF;
sj = s_data[(j/4)*32+threadIdx.x];
shiftj = 8*(j%4);
v = (sj >> shiftj) & 0xff;
si = (si & 0xffffff00) | v;
sj = (sj & ~(0xFFu << (8*(j%4)))) | (u << shiftj);
s_data[(j/4)*32+threadIdx.x] = sj;
u = (si >> 8) & 0xff;
j = (j + k1 + u) & 0xFF;
sj = s_data[(j/4)*32+threadIdx.x];
shiftj = 8*(j%4);
v = (sj >> shiftj) & 0xff;
si = (si & 0xffff00ff) | (v<<8);
sj = (sj & ~(0xFFu << (8*(j%4)))) | (u << shiftj);
s_data[(j/4)*32+threadIdx.x] = sj;
u = (si >> 16) & 0xff;
j = (j + k2 +u) & 0xFF;
sj = s_data[(j/4)*32+threadIdx.x];
shiftj = 8*(j%4);
v = (sj >> shiftj) & 0xff;
si = (si & 0xff00ffff) | (v<<16);
sj = (sj & ~(0xFFu << (8*(j%4)))) | (u << shiftj);
s_data[(j/4)*32+threadIdx.x] = sj;
u = (si >> 24) & 0xff;
j = (j + k3 + u) & 0xFF;
sj = s_data[(j/4)*32+threadIdx.x];
shiftj = 8*(j%4);
v = (sj >> shiftj) & 0xff;
si = (si & 0xffffff) | (v<<24);
sj = (sj & ~(0xFFu << (8*(j%4)))) | (u << shiftj);
s_data[(j/4)*32+threadIdx.x] = sj;
s_data[(i/4)*32+threadIdx.x] = si;
}
d_out[in] = s_data[threadIdx.x]; // unrelevant debug output
}
其實,我正在老年人'特斯拉'架構下工作,所以__byte_perm內在(這似乎很好知道)不能使用。我的性能比較是由我用同一個gpu卡製作的基準測試時間確定的。 – bluzorange
我在Schneier中查找了RC4,它是一個使用由256個單字節條目組成的SBOX的面向字節的算法。您的代碼似乎一次只能訪問一個字節的字節數組,並在運行時提取並插入字節。這些提取/插入似乎佔用了這個計算約束任務總體執行時間的很大一部分。您是否考慮將每個SBOX元素存儲在一個字中,僅在您寫回每個SBOX條目時屏蔽掉最低有效字節?另外嘗試通過char數組而不是字數組來使用輸入數據。 – njuffa