我对cuda很新.我在设备仿真模式下在我的ubuntu 10.04上使用cuda.我编写了一个代码来计算以下数组的平方:
#include <stdio.h>
#include <cuda.h>
__global__ void square_array(float *a, int N)
{
int idx = blockIdx.x + threadIdx.x;
if (idx<=N)
a[idx] = a[idx] * a[idx];
}
int main(void)
{
float *a_h, *a_d;
const int N = 10;
size_t size = N * sizeof(float);
a_h = (float *)malloc(size);
cudaMalloc((void **) &a_d, size);
for (int i=0; i<N; i++) a_h[i] = (float)i;
cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice);
square_array <<< 1,10>>> (a_d, N);
cudaMemcpy(a_h, a_d, sizeof(float)*N, cudaMemcpyDeviceToHost);
// Print results
for (int i=0; i<N; i++) printf(" %f\n", a_h[i]);
free(a_h);
cudaFree(a_d);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时它显示没有问题它给我正确的输出.
现在我的问题是,当我使用<<< 2,5 >>>或<<< 5,2 >>>时,结果是一样的.在gpu上发生了什么?我所理解的是,我只需要启动包含2个线程的5个块的cuda内核.任何人都可以解释我如何处理这个或实现启动(内核调用)?
现在我真正的问题是,当我用<<< 1,10 >>调用内核时,它没问题.它显示了完美的结果.但是当我用<<< 1,5 >>调用内核时,结果如下:
0.000000
1.000000
4.000000
9.000000
16.000000
5.000000
6.000000
7.000000
8.000000
9.000000
Run Code Online (Sandbox Code Playgroud)
类似地,当我减少或增加内核调用中的第二个参数时,它显示不同的结果,例如当我将其更改为<< 1,4 >>时,它显示以下结果:
0.000000
1.000000
4.000000
9.000000
4.000000
5.000000
6.000000
7.000000
8.000000
9.000000
Run Code Online (Sandbox Code Playgroud)
为什么这个结果会来?任何机构都可以解释内核启动调用的工作吗?
什么是blockdim类型变量包含?请帮助我理解内核调用启动和工作的概念?我搜索了编程指南,但他们没有很好地解释它.
idx
内核代码中的计算不正确.如果您将其更改为:
int idx = blockDim.x * blockIdx.x + threadIdx.x;
Run Code Online (Sandbox Code Playgroud)
您可能会发现结果更容易理解.
编辑:对于任何给定的内核启动
square_array<<<gridDim,blockDim>>>(...)
Run Code Online (Sandbox Code Playgroud)
在GPU中,自动变量blockDim将包含在主机端内核启动中传递的blockDim参数的x,y和z组件.类似地,gridDim将包含在启动时传递的gridDim参数的x和y分量.
归档时间: |
|
查看次数: |
300 次 |
最近记录: |