cuda - CUDA 数据数不能被 CUDA 线程平均分配
问题描述
比如有两个4线程,但是我有5个数据,第一个0-3可以映射到前4个线程,剩下的呢,它只说可能有运行时错误,但是如何修复它?
我想我问这个问题的方向是错误的,现在假设我有
perfromwork<<<2,2>>>;
现在我这个伪代码计算出来的dataIndex小于数据元素个数(N=5),那么最后一个(5-2x2=1)怎么办?如果我使用另一个块,它会遇到同样的问题,<<<2, 2>>> 块将创建一个更大的数据索引。
解决方案
这里有两种规范的方法。
将网格大小设置为大于或等于数据集大小,并确保使用“线程检查”来防止不需要的额外线程进行任何工作。
使用grid-stride loop,它允许独立于数据集大小(如果您愿意)确定网格大小,同时仍然提供正确的结果。
vector 为每个添加示例内核:
__global__ void vectorAdd(float *x, float *y, float *z, int size){
int idx = threadIdx.x+blockDim.x*blockIdx.x;
if (idx < size) // thread check
z[idx] = x[idx] + y[idx];
}
上面的内核不使用网格步长循环。它将要求您将网格的大小设置为大于或等于数据集大小,以便处理所有元素。该大小调整代码可能如下所示:
int size = MY_DATA_SET_SIZE;
dim3 block(256); // this is threads per block, the choice here is not critical for correctness, but must be 1 or larger and less than or equal to 1024;
dim3 grid((size+block.x-1)/block.x);
vectorAdd<<<grid,block>>>(...);
实现网格步长循环以执行相同操作的内核可能如下所示:
__global__ void vectorAdd(float *x, float *y, float *z, int size){
for (int idx = threadIdx.x+blockDim.x*blockIdx.x; idx < size; idx += blockDim.x*gridDim.x)
z[idx] = x[idx] + y[idx];
}
在这种情况下,网格大小可以是任意的(1 或更大)并且仍然会产生正确的结果。
推荐阅读
- navigation - ROS 导航:本地成本图不适用于自定义图层
- javascript - 返回浏览器按钮时修改 URL GET 变量
- java - 财产文件中的预定费率
- python - 如何在python中选择要写入的文本文件的哪一行
- android - 本地存储选项(例如 LocalStorage、IndexedDB 和 WebSQL)能否用于 Android/IOS 应用程序?
- java - jsf注入列表给了我NullpointerException
- javascript - 如何在异步函数之间共享变量?
- asp.net-mvc - Asp.net (VB.net) MVC 将修改后的模型传回控制器
- python - 将具有多个条件的 for 循环转换为理解
- tensorflow - ImageDataGenerator 不执行指定的转换