1
我有2
內核,它們完全相同。其中一個靜態分配共享內存,另一個在運行時動態分配內存。我使用共享內存作爲二維數組。所以對於動態分配,我有一個計算內存位置的宏。現在,2
內核生成的結果完全相同。但是,我從兩個內核獲得的時序結果相差3
倍!靜態內存分配要快得多。我很抱歉,我無法發佈我的任何代碼。有人可以給這個理由嗎?靜態與動態CUDA共享內存分配的性能
我有2
內核,它們完全相同。其中一個靜態分配共享內存,另一個在運行時動態分配內存。我使用共享內存作爲二維數組。所以對於動態分配,我有一個計算內存位置的宏。現在,2
內核生成的結果完全相同。但是,我從兩個內核獲得的時序結果相差3
倍!靜態內存分配要快得多。我很抱歉,我無法發佈我的任何代碼。有人可以給這個理由嗎?靜態與動態CUDA共享內存分配的性能
我沒有證據表明靜態共享內存分配比動態共享內存分配快。正如上面的評論所證明的那樣,沒有一個複製者就不可能回答你的問題。在下面的代碼中的至少的情況下,相同的內核的定時,當與靜態或動態共享存儲器分配運行,是完全一樣的:
#include <cuda.h>
#include <stdio.h>
#define BLOCK_SIZE 512
/********************/
/* CUDA ERROR CHECK */
/********************/
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, char *file, int line, bool abort=true)
{
if (code != cudaSuccess)
{
fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
if (abort) exit(code);
}
}
/***********************************/
/* SHARED MEMORY STATIC ALLOCATION */
/***********************************/
__global__ void kernel_static_memory_allocation(int *d_inout, int N)
{
__shared__ int s[BLOCK_SIZE];
const int tid = threadIdx.x;
const int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < N) {
s[tid] = d_inout[i];
__syncthreads();
s[tid] = s[tid] * s[tid];
__syncthreads();
d_inout[i] = s[tid];
}
}
/************************************/
/* SHARED MEMORY DYNAMIC ALLOCATION */
/************************************/
__global__ void kernel_dynamic_memory_allocation(int *d_inout, int N)
{
extern __shared__ int s[];
const int tid = threadIdx.x;
const int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < N) {
s[tid] = d_inout[i];
__syncthreads();
s[tid] = s[tid] * s[tid];
__syncthreads();
d_inout[i] = s[tid];
}
}
/********/
/* MAIN */
/********/
int main(void)
{
int N = 1000000;
int* a = (int*)malloc(N*sizeof(int));
for (int i = 0; i < N; i++) { a[i] = i; }
int *d_inout; gpuErrchk(cudaMalloc(&d_inout, N * sizeof(int)));
int n_blocks = N/BLOCK_SIZE + (N%BLOCK_SIZE == 0 ? 0:1);
gpuErrchk(cudaMemcpy(d_inout, a, N*sizeof(int), cudaMemcpyHostToDevice));
float time;
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);
kernel_static_memory_allocation<<<n_blocks,BLOCK_SIZE>>>(d_inout, N);
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaDeviceSynchronize());
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&time, start, stop);
printf("Static allocation - elapsed time: %3.3f ms \n", time);
cudaEventRecord(start, 0);
kernel_dynamic_memory_allocation<<<n_blocks,BLOCK_SIZE,BLOCK_SIZE*sizeof(int)>>>(d_inout, N);
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaDeviceSynchronize());
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
cudaEventElapsedTime(&time, start, stop);
printf("Dynamic allocation - elapsed time: %3.3f ms \n", time);
}
可能的原因是由於這樣的事實兩個內核的反彙編代碼是完全相同的,即使將替換爲int N = rand();
也不會改變。
您是否使用'-ptx'選項調查了NVCC產生的PTX代碼?如果輸出代碼存在明顯差異,這可能有助於解釋爲什麼一個內核更快。 – Heatsink
它可能與編譯器優化有關。你可以嘗試使用-O0選項編譯這兩個代碼嗎? – pQB
您確定您的動態大小計算與靜態數組的大小相同嗎?如果它更大(可能是錯誤的),那麼你可能會減少內核的佔用率。順便說一句,要得到任何實際的答案,你需要提供實際的細節 - 一個代碼示例。 – harrism