CUDA内核自动调用内核来完成向量加法.为什么?
CUDA kernel automatically recall kernel to finish vector addition. Why?
我刚开始玩CUDA,所以我尝试了一个教科书式的矢量加法代码。然而,当我指定内核调用只添加向量的前半部分时,后半部分也会被添加!当我包含一些推力库头时,这种行为就会停止。
我完全糊涂了。请参阅下面的代码:
#include <iostream>
using namespace std;
__global__ void VecAdd(float *d_dataA, float *d_dataB, float *d_resultC)
{
//printf("gridDim.x is %d n",gridDim.x);
int tid = blockIdx.x * blockDim.x + threadIdx.x;
// printf("tid is %d n",tid);
d_resultC[tid] = d_dataA[tid] + d_dataB[tid];
}
int main()
{
const int ARRAY_SIZE = 8*1024;
const int ARRAY_BYTES = ARRAY_SIZE * sizeof(float);
float *h_dataA, *h_dataB, *h_resultC;
float *d_dataA, *d_dataB, *d_resultC;
h_dataA = (float *)malloc(ARRAY_BYTES);
h_dataB = (float *)malloc(ARRAY_BYTES);
h_resultC = (float *)malloc(ARRAY_BYTES);
for(int i=0; i<ARRAY_SIZE;i++){
h_dataA[i]=i+1;
h_dataB[i]=2*(i+1);
};
cudaMalloc((void **)&d_dataA,ARRAY_BYTES);
cudaMalloc((void **)&d_dataB,ARRAY_BYTES);
cudaMalloc((void **)&d_resultC,ARRAY_BYTES);
cudaMemcpy(d_dataA, h_dataA,ARRAY_BYTES, cudaMemcpyHostToDevice);
cudaMemcpy(d_dataB, h_dataB,ARRAY_BYTES, cudaMemcpyHostToDevice);
cout << h_resultC[0] << endl;
cout << h_resultC[ARRAY_SIZE-1] << endl;
dim3 dimBlock(ARRAY_SIZE/8,1,1);
dim3 dimGrid(1,1,1);
VecAdd<<<dimGrid,dimBlock>>>(d_dataA, d_dataB, d_resultC);
cout << h_resultC[0] << endl;
cout << h_resultC[ARRAY_SIZE-1] << endl;
cudaMemcpy(h_resultC,d_resultC ,ARRAY_BYTES,cudaMemcpyDeviceToHost);
cout << h_resultC[0] << endl;
cout << h_resultC[ARRAY_SIZE-1] << endl;
return 0;
}
您是否先用ARRAY_SIZE线程启动它,然后用其中一半线程启动它?(或1/8)
您没有初始化d_resultC,所以d_resultC可能具有以前执行的结果。这可以解释这种行为,但也许不是。
在d_result_C上添加一个cudaMemset并告诉我们发生了什么。
我无法确定为什么内核处理的元素比预期的要多。它每个线程处理一个元素,所以处理的元素数量肯定应该是blockDim.x*gridDim.x。
不过,我想指出的是,编写使用"网格步长循环"的内核是一种很好的做法,这样它们就不会那么依赖于块和线程数。性能成本可以忽略不计,如果您对性能敏感,不同GPU的阻塞参数也会不同。
http://cudahandbook.to/15QbFWx
因此,您应该添加一个计数参数(要处理的元素数量),然后编写以下内容:
__global__ void VecAdd(float *d_dataA, float *d_dataB, float *d_resultC, int N)
{
for ( int i = blockIdx.x*blockDim.x + threadIdx.x;
i < N;
i += blockDim.x*gridDim.x ) {
d_resultC[i] = d_dataA[i] + d_dataB[i];
}
}
正如上面提到的一些人。这可能是由于上次运行的剩余数据造成的。你没有释放你分配的内存可能是造成这种奇怪情况的原因。我认为您应该使用free
释放主机上分配的阵列,并使用CudaFree
释放GPU上的内存
此外,我强烈建议您使用CudaMallocHost
而不是malloc
分配主机内存,并在程序结束时使用CudaFreeHost
释放它们。这将为您提供快速复制。请参阅此处:CudaMallocHost
无论如何,不要忘记在C/C++程序上释放堆内存,无论是否使用CUDA。
相关文章:
- 写入向量<向量<bool>>
- 函数向量_指针有不同的原型,我可以构建一个吗
- std::向量与传递值的动态数组
- 将值指定给向量(2D)的向量中的某个位置
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 如何使用向量的template_back函数
- 尝试通过多个向量访问变量时,向量下标超出范围
- 如何通过派生类函数更改基类中的向量
- C++从另一个类访问公共静态向量的正确方法是什么
- 如何将ampl中的集合表示为c++中的向量
- 变量没有改变?通过向量的函数调用
- 迭代时从向量和内存中删除对象
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- OpenCL 是否支持向量作为内核参数?
- Cuda 内核返回向量
- 如何在CUDA内核中添加向量元素
- 如何将C++向量传递和访问到OpenCL内核
- CUDA内核自动调用内核来完成向量加法.为什么?
- 在 cuda 内核中创建向量
- 两个单精度浮点向量的点积在 CUDA 内核中产生的结果与在主机上的结果不同