CUDA:达到 blockIdx.x 的最大可能值,用于计算能力 3.0
CUDA: Hitting the maximum possible value of blockIdx.x for compute capability 3.0
首先,我应该说我对C++编程很陌生(更不用说CUDA(,尽管这是我大约184年前第一次学到的。我会说我有点与内存分配和数据类型大小脱节,尽管我正在学习。无论如何,这里是:
我有一个具有计算能力 3.0 的 GPU(它是带有 2GB DRAM 的 Geforce 660 GTX(。
通过 CUDA 示例中找到的 ./deviceQuery(以及我在网上找到的其他图表(,列出了我的最大网格大小:
Max dimension size of a grid size (x,y,z): (2147483647, 65535, 65535)
在 2,147,483,647 (2^31-1( 处,x 维度很大,而且有点不错......然而,当我运行我的代码,在 x 维度上超过 65535 时,事情变得......奇怪。
我使用了Udacity课程中的一个例子,并对其进行了修改以测试极端情况。我保持内核代码相当简单来证明这一点:
__global__ void referr(long int *d_out, long int *d_in){
long int idx = blockIdx.x;
d_out[idx] = idx;
}
请注意,下面的ARRAY_SIZE
是网格的大小,也是要对其进行操作的整数数组的大小。我将块的大小保留为 1x1x1。只是为了理解限制,我知道只有 1 个线程的块进行这么多操作是没有意义的,但我想了解网格大小限制是怎么回事。
int main(int argc, char ** argv) {
const long int ARRAY_SIZE = 522744;
const long int ARRAY_BYTES = ARRAY_SIZE * sizeof(long int);
// generate the input array on the host
long int h_in[ARRAY_SIZE];
for (long int i = 0; i < ARRAY_SIZE; i++) {
h_in[i] = i;
}
long int h_out[ARRAY_SIZE];
// declare GPU memory pointers
long int *d_in;
long int *d_out;
// allocate GPU memory
cudaMalloc((void**) &d_in, ARRAY_BYTES);
cudaMalloc((void**) &d_out, ARRAY_BYTES);
// transfer the array to the GPU
cudaMemcpy(d_in, h_in, ARRAY_BYTES, cudaMemcpyHostToDevice);
// launch the kernel with ARRAY_SIZE blocks in the x dimension, with 1 thread each.
referr<<<ARRAY_SIZE, 1>>>(d_out, d_in);
// copy back the result array to the CPU
cudaMemcpy(h_out, d_out, ARRAY_BYTES, cudaMemcpyDeviceToHost);
// print out the resulting array
for (long int i =0; i < ARRAY_SIZE; i++) {
printf("%li", h_out[i]);
printf(((i % 4) != 3) ? "t" : "n");
}
cudaFree(d_in);
cudaFree(d_out);
return 0;
}
这在 MOST 65535 的 MOST ARRAY_SIZE
下按预期工作。下面是输出的最后几行
65516 65517 65518 65519
65520 65521 65522 65523
65524 65525 65526 65527
65528 65529 65530 65531
65532 65533 65534
如果我将ARRAY_SIZE
推到此之外,输出将变得非常不可预测,最终如果数字变得太高,我会收到一条Segmentation fault (core dumped)
消息......不管这意味着什么。即。ARRAY_SIZE
为 65536:
65520 65521 65522 65523
65524 65525 65526 65527
65528 65529 65530 65531
65532 65533 65534 131071
为什么现在说最后一个的blockIdx.x是131071??即 65535+65535+1。奇怪。
更奇怪的是,当我将ARRAY_SIZE
设置为 65537 (65535+2( 时,输出的最后一行得到了一些非常奇怪的结果。
65520 65521 65522 65523
65524 65525 65526 65527
65528 65529 65530 65531
65532 65533 65534 131071
131072 131073 131074 131075
131076 131077 131078 131079
131080 131081 131082 131083
131084 131085 131086 131087
131088 131089 131090 131091
131092 131093 131094 131095
131096 131097 131098 131099
131100 131101 131102 131103
131104 131105 131106 131107
131108 131109 131110 131111
131112 131113 131114 131115
131116 131117 131118 131119
131120 131121 131122 131123
131124 131125 131126 131127
131128 131129 131130 131131
131132 131133 131134 131135
131136 131137 131138 131139
131140 131141 131142 131143
131144 131145 131146 131147
131148 131149 131150 131151
131152 131153 131154 131155
131156 131157 131158 131159
131160 131161 131162 131163
131164 131165 131166 131167
131168 131169 131170 131171
131172 131173 131174 131175
131176 131177 131178 131179
131180 131181 131182 131183
131184 131185 131186 131187
131188 131189 131190 131191
131192 131193 131194 131195
131196 131197 131198 131199
131200
65535 不是旧 GPU 的限制吗?为什么当我突破 x 网格维度的 65535 障碍时,我的 GPU "搞砸了"?还是这是设计使然?这到底是怎么回事?
哇,对不起,这个问题很长。
任何帮助理解这一点将不胜感激!谢谢!
您应该使用正确的 CUDA 错误检查 .并且,在使用 nvcc 进行编译时,您应该通过指定-arch=sm_30
来针对计算 3.0 体系结构进行编译。
- C++用于计算移动平均线的程序
- (此函数用于计算 SMA).在 FA.exe 中0x00509159引发异常: 0xC0000005:访问冲突读取位置0
- 应该如何编写用于计算最近点距离的C++函数?
- 递归函数,用于计算 BST 中具有两个子节点的节点数
- 用于计算字符串中元音的函数
- 用于计算文本宽度的模块
- 用于计算周长和面积的程序,而不是从 void 函数输出值
- 用于计算统一子字符串权重的代码
- 递归函数用于计算 n 个数字之和的意外输出
- 一个递归函数,用于计算 n-airy 树的高度
- MFC 用于计算控件的高光、阴影等的算法或函数是什么?
- 递归函数,用于计算数字中的位数
- 该递归代码用于计算指数的运行时间是多少
- 用于计算不包含给定数字的第n个数字的程序
- 基本案例背后的直觉用于计算步骤数
- 用于计算平均值的C++程序
- 用于计算来自不同实例的响应数的编码技术
- 像儒略数字用于计算日期一样,是否有任何特定的数字来计算时间
- OpenCV Mahalanobis函数,用于计算两个图像之间的距离
- maxi 和 min 时间,用于计算在 n 处进行六次单独运行的斐波那契数