gpt4 book ai didi

c++ - CUDA 对大量线程的奇怪行为

转载 作者:太空宇宙 更新时间:2023-11-04 11:30:59 24 4
gpt4 key购买 nike

我想准备我的 CUDA 内核以处理大量粒子(远远超过 65535,这是 gridDim 的最大值)。我试图为任何 <<<numBlocks, threadsPerBlock>>> 创建一个合适的线程索引映射值(value)观。

我是这样写的:

__global__ void step_k(float* position, size_t numElements, unsigned int* blabla) 
{
unsigned int i = calculateIndex();

if (i < numElements){
blabla[i] = i;
}
}

__device__ unsigned int calculateIndex(){
unsigned int xIndex = blockIdx.x*blockDim.x+threadIdx.x;
unsigned int yIndex = blockIdx.y*blockDim.y+threadIdx.y;
unsigned int zIndex = blockIdx.z*blockDim.z+threadIdx.z;

unsigned int xSize = gridDim.x*blockDim.x;
unsigned int ySize = gridDim.y*blockDim.y;

return xSize*ySize*zIndex+xSize*yIndex+xIndex;
}

我这样使用它:

void CudaSphFluids::step(void)
{
//dim3 threadsPerBlock(1024, 1024, 64);
//dim3 numBlocks(65535, 65535, 65535);

dim3 numBlocks(1, 1, 1);
dim3 threadsPerBlock(256, 256, 1);

unsigned int result[256] = {};
unsigned int* d_results;
cudaMalloc( (void**) &d_results,sizeof(unsigned int)*256);

step_k<<<numBlocks, threadsPerBlock>>>(d_position, 256, d_results);

cudaMemcpy(result,d_results,sizeof(unsigned int)*256,cudaMemcpyDeviceToHost);

CLOG(INFO, "SPH")<<"STEP";
for(unsigned int t=0; t<256;t++) {
cout<<result[t]<<"; ";
}
cout<<endl;

cudaFree(d_results);
Sleep(200);
}

这似乎没问题(从 0 到 255 递增数字):

dim3 numBlocks(1, 1, 1);
dim3 threadsPerBlock(256, 1, 1);

适用于:

dim3 numBlocks(1, 1, 1);
dim3 threadsPerBlock(256, 3, 1);

但是当我尝试运行它时:

dim3 numBlocks(1, 1, 1);
dim3 threadsPerBlock(256, 5, 1);

enter image description here

对于:

dim3 numBlocks(1, 1, 1);
dim3 threadsPerBlock(256, 10, 1);

enter image description here

对于较大的值,例如:

dim3 numBlocks(1, 1, 1);
dim3 threadsPerBlock(256, 256, 1);

越来越疯狂了:

enter image description here

然后我尝试使用某个聪明人网站上的另一个映射:

__device__ int getGlobalIdx_3D_3D()
{
int blockId = blockIdx.x
+ blockIdx.y * gridDim.x
+ gridDim.x * gridDim.y * blockIdx.z;
int threadId = blockId * (blockDim.x * blockDim.y * blockDim.z)
+ (threadIdx.z * (blockDim.x * blockDim.y))
+ (threadIdx.y * blockDim.x)
+ threadIdx.x;
return threadId;
}

但不幸的是它不起作用。 (数字不一样,也是错误的)。

知道这种奇怪行为的原因是什么吗?

我在 GeForce GTX 560Ti (sm_21) 和带有 NSight 的 VS2012 上使用 CUDA 6.0。

最佳答案

每个 block 请求 65536 个线程:

dim3 threadsPerBlock(256, 256, 1);

这在任何当前的 CUDA GPU 上都是 Not Acceptable ,它们是 limited to either 512 or 1024 threads per block .

这些也为每个 block 启动了太多线程:

dim3 threadsPerBlock(256, 5, 1);
dim3 threadsPerBlock(256, 10, 1);

首先添加 proper cuda error checking到你的程序。我建议在此处发布之前对任何 CUDA 代码执行此操作。您将获得更多信息,其他人将能够更好地帮助您。

虽然您没有显示完整的内核,但您的内核索引似乎已针对 3D 索引正确设置。因此,可能只需要修改这一行:

dim3 numBlocks(1, 1, 1);

您可能希望通过 GPU 获得合理的性能。

关于c++ - CUDA 对大量线程的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24763102/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com