使用 CUDA 并行化四个或更多嵌套循环
Parallelize four and more nested loops with CUDA
我正在研究一个生成并行C++代码的编译器。我是 CUDA 编程的新手,但我正在尝试使用 CUDA 并行化C++代码。
目前,如果我有以下顺序C++代码:
for(int i = 0; i < a; i++) {
for(int j = 0; j < b; j++) {
for(int k = 0; k < c; k++) {
A[i*y*z + j*z + k*z +l] = 1;
}
}
}
这将产生以下 CUDA 代码:
__global__ void kernelExample() {
int _cu_x = ((blockIdx.x*blockDim.x)+threadIdx.x);
int _cu_y = ((blockIdx.y*blockDim.y)+threadIdx.y);
int _cu_z = ((blockIdx.z*blockDim.z)+threadIdx.z);
A[_cu_x*y*z + _cu_y*z + _cu_z] = 1;
}
因此,每个循环嵌套都映射到一个维度,但是并行化四个或更多嵌套循环的正确方法是什么:
for(int i = 0; i < a; i++) {
for(int j = 0; j < b; j++) {
for(int k = 0; k < c; k++) {
for(int l = 0; l < d; l++) {
A[i*x*y*z + j*y*z + k*z +l] = 1;
}
}
}
}
有没有类似的方法?值得注意的是:所有循环维度都是平行的,迭代之间没有依赖关系。
提前感谢!
编辑:目标是将所有迭代映射到 CUDA 线程,因为所有迭代都是独立的并且可以并发执行。
您可以保持外部循环不变。此外,最好将.x
用作最内部的循环,以便您可以有效地访问全局内存。
__global__ void kernelExample() {
int _cu_x = ((blockIdx.x*blockDim.x)+threadIdx.x);
int _cu_y = ((blockIdx.y*blockDim.y)+threadIdx.y);
int _cu_z = ((blockIdx.z*blockDim.z)+threadIdx.z);
for(int i = 0; i < a; i++) {
A[i*x*y*z + _cu_z*y*z + _cu_y*z + _cu_x] = 1;
}
}
但是,如果a,b,c,d
都非常小,则可能无法获得足够的并行度。在这种情况下,您可以将线性索引转换为 n-D 索引。
__global__ void kernelExample() {
int tid = ((blockIdx.x*blockDim.x)+threadIdx.x);
int i = tid / (b*c*d);
int j = tid / (c*d) % b;
int k = tid / d % c;
int l = tid % d;
A[i*x*y*z + j*y*z + k*z + l] = 1;
}
但请注意,计算i,j,k,l
可能会引入大量开销,因为整数除法和 mod 在 GPU 上很慢。作为替代方案,您可以将i,j
映射到.z
和.y
,并以类似的方式仅从.x
计算k,l
和更多维度。
相关文章:
- 如何在C++中创建 if else 循环而不是多个嵌套?
- 2 个嵌套循环的时间复杂度
- 为什么使用 2 个嵌套循环 O(n^2) 复杂度来解决二和问题,当只改变循环计数器逻辑时运行得更快?
- 两个嵌套循环的运行时间复杂性:二次型还是线性
- 如何在不将其拆分为两个嵌套循环的情况下打印整个形状?
- 使用嵌套循环搜索两个向量并查看其属性
- 概括多个嵌套以循环
- 如何将3个嵌套循环重写为一个
- 优化四重嵌套"for"循环
- 执行三个嵌套for循环的最快方法是什么
- 将三个嵌套的 for 循环包装成递归
- 使用 CUDA 并行化四个或更多嵌套循环
- 使用 tbb 并行多个嵌套循环
- 多个嵌套for循环与单个for循环
- 2 个对数嵌套循环的 Theta 运行时
- 嵌套循环,用于显示 25 个字符的行 c++
- 为什么具有多个嵌套循环的代码可以在 GCC 上立即完成,但在 VS 上需要很长时间
- 两个嵌套循环的非递归归并排序
- 用1和0填充一个大矩阵——6个嵌套循环
- 一般三个嵌套循环的 O(n^3) 复杂度的数学推导