我在这里展示一些代码
__constant__ int array[1024];
__global__ void kernel1(int *d_dst) {
int tId = threadIdx.x + blockIdx.x * blockDim.x;
d_dst[tId] = array[tId];
}
__global__ void kernel2(int *d_dst, int *d_src) {
int tId = threadIdx.x + blockIdx.x * blockDim.x;
d_dst[tId] = d_src[tId];
}
int main(int argc, char **argv) {
int *d_array;
int *d_src;
cudaMalloc((void**)&d_array, sizeof(int) * 1024);
cudaMalloc((void**)&d_src, sizeof(int) * 1024);
int *test = new int[1024];
memset(test, 0, sizeof(int) * 1024);
for (int i = 0; i < 1024; i++) {
test[i] = 100;
}
cudaMemcpyToSymbol(array, test, sizeof(int) * 1024);
kernel1<<< 1, 1024 >>>(d_array);
cudaMemcpy(d_src, test, sizeof(int) * 1024, cudaMemcpyHostToDevice);
kernel2<<<1, 32 >>>(d_array, d_src),
free(test);
cudaFree(d_array);
cudaFree(d_src);
return 0;
}
它只是显示了常量内存和全局内存使用情况。在执行时,“kernel2”的执行速度(就时间而言)比“kernel1”快 4 倍
我从 Cuda C 编程指南中了解到,这是因为对常量内存的访问正在被序列化。这让我想到,如果扭曲访问单个常量值(例如整数、浮点数、双精度等),则可以最好地利用常量内存,但访问数组根本没有好处。换句话说,我可以说扭曲必须访问单个地址,以便从持续的内存访问中获得任何有益的优化/加速收益。这个对吗?
我也想知道,如果我在我的常量内存中保留一个结构而不是简单类型。线程对结构的任何访问;也被认为是单个内存访问或更多?我的意思是一个结构可能包含多个简单的类型和数组,例如;在访问这些简单类型时,这些访问是否也被序列化了?
最后一个问题是,如果我确实有一个具有常量值的数组,需要通过扭曲中的不同线程访问它;为了更快地访问它应该保存在全局内存而不是常量内存中。那是对的吗?
任何人都可以向我推荐一些示例代码,其中显示了有效的恒定内存使用情况。
问候,