這是一個與性能相關的問題。我已經寫了基於「CUDA按示例」示例代碼以下簡單的CUDA內核:CUDA共享內存速度
#define N 37426 /* the (arbitrary) number of hashes we want to calculate */
#define THREAD_COUNT 128
__device__ const unsigned char *m = "Goodbye, cruel world!";
__global__ void kernel_sha1(unsigned char *hval) {
sha1_ctx ctx[1];
unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;
while(tid < N) {
sha1_begin(ctx);
sha1_hash(m, 21UL, ctx);
sha1_end(hval+tid*SHA1_DIGEST_SIZE, ctx);
tid += blockDim.x * gridDim.x;
}
}
的代碼在我看來是正確的,確實吐出相同的散列的37426份(如基於預期在我閱讀第5章第5.3節時,我認爲寫入全局內存的每個線程都以「hval」的形式傳入,效率極低。
然後,我實現了我認爲會使用共享的性能提升緩存代碼修改如下:
#define N 37426 /* the (arbitrary) number of hashes we want to calculate */
#define THREAD_COUNT 128
__device__ const unsigned char *m = "Goodbye, cruel world!";
__global__ void kernel_sha1(unsigned char *hval) {
sha1_ctx ctx[1];
unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;
__shared__ unsigned char cache[THREAD_COUNT*SHA1_DIGEST_SIZE];
while(tid < N) {
sha1_begin(ctx);
sha1_hash(m, 21UL, ctx);
sha1_end(cache+threadIdx.x*SHA1_DIGEST_SIZE, ctx);
__syncthreads();
if(threadIdx.x == 0) {
memcpy(hval+tid*SHA1_DIGEST_SIZE, cache, sizeof(cache));
}
__syncthreads();
tid += blockDim.x * gridDim.x;
}
}
第二個版本似乎也能正常運行,但比初始版本慢幾倍。後者代碼在大約8.95毫秒內完成,而前者在大約1.64毫秒內執行。我對Stack Overflow社區的問題很簡單:爲什麼?
非常感謝您經過深思熟慮的回覆。代碼鬆散地基於一些示例,但是我從頭開始編寫它。 sha1_ *函數是我沒有在我的文章中包含的庫的一部分。他們從一個輸入(在這種情況下是一個字符串)計算SHA1哈希值。它們不是CUDA運行時的一部分。 – Shiba
在百靈之際,我評論了__syncthreads()調用來衡量其性能影響。差異可以忽略不計:其他因素導致5倍的性能損失。全局內存寫入每塊相鄰。感謝您參考合併:如果本書提到它,我錯過了它。我會看看你鏈接到的網絡研討會。 – Shiba
是的,sha1_end每個線程寫入全局內存一次。它採用ctx中的狀態並將160位SHA1哈希寫入hval。 – Shiba