如何为八维设置我的Cuda螺纹块和网格?

时间:2013-06-11 16:07:43

标签: cuda dimension

我定期做三维cuda工作,但现在我有八个维度的问题。

如何为八个维度设置我的线程块和网格?

例如在3d中我使用:

    grid.x=int(321);  
    grid.y=int(321);

    foo<<<grid,int(321)>>>

因此每个线程都获得它自己的x,y,z地址,并尝试仅使用x,y,z来解决问题。如果结果是积极的结果得到报告。我知道如何传递内存指针来报告结果。

现在我遇到了一个新问题,我希望在八个不同的轴上尝试0到11的值,而在三个上尝试0到321的值。我假设每个线程都应该通过线程块,网格获得它的(a,b,c,d,e,f,g,h)参数集。

如何通过网格和块大小将八个维度映射到我的内核中?

2 个答案:

答案 0 :(得分:1)

网格的2D特性和块的3D特性只是NVIDIA的一个便利;他们可能只接受那里的单个整数,硬件也会以同样的方式工作。这就是为什么,如果您的问题本身不是2D或3D,我建议使用单维索引并在需要时“拆分”索引。像这样:

int grid = 65536;
int block = 256;
foo<<<grid,block>>>();

然后在您的设备代码中:

__device__ int globalIndex() { blockIdx.x * blockDim.x + threadIdx.x; }

__device__ int index8D(int dim) { return (globalIndex() >> (dim*3))%8 }

在上面的示例中,通过调用index8D(i),您将获得与当前线程对应的i坐标。但是,有效坐标仅在0到7的范围内。您将需要更多线程来增加该范围...

警告!八维立方体,每个维度的细胞甚至很少! 如果您的8D空间仅在[0..7]上进行迭代,那么我们正在查看8^8个单元格(16777216)。您可能需要考虑让一个线程实际迭代几个单元格。


解释index8D的内部结构:我基本上将全局线程索引的二进制表示分成每个维度3位的组:

101 110 001 000 110 001 101 110

每个组现在代表其中一个维度的索引。左移和模数用于提取相应的3位组。 (计算模数常量将由编译器针对逐位运算进行优化;为了便于阅读,我将其保留为原样)

答案 1 :(得分:0)

这是我对我的问题的回答,一个简短的Cuda程序,在八轴上找到无单位方程。第二行的搜索大小应该是大于5的奇数。程序以行形式输出c0 h0 A0 R0 W0 G0 N0 F0的功率。

我可能错了,但我认为结构是旧学校的短路逻辑结构。线程分歧并报告正确的答案;否则线程会收敛并以错误的速度全速运行!

这是无单位方程,对于常数的幂,我正在解决。我认为这个程序很粗糙,因为这个等式很粗糙。每个括号组必须为零才能使方程成立。可以像我的方法一样使用正方形或绝对或纯逻辑。

(X4-X5)^ 2 +(X3 + X8)^ 2 +(X4 + X7 + X8)^ 2 +(X2 + X4-5233)^ 2 +( - 2 *(4 + 5233)+ x8的-x1-x2)^ 2 +(2 *(x2 + x4)+ x1 + x5 + 3 * x6)^ 2 = 0

代码减慢了正确的答案;但它们很少见,因此它大部分时间都接近全速运行。一旦找到,正确的答案很容易检查。保留所有权利,M。Snyder 2013年6月我已经在8轴上累了0到59的范围,它在GTX 560上运行了几个小时。现在尝试在我的GTX 480上使用0到95的范围。

如果有人能帮助我让它跑得更快,我会感兴趣的......

#include "stdio.h"
#define searchsize 27
//nvcc helloworld.cu -o helloworld -arch=sm_21 -maxrregcount=20 -ccbin=gcc-4.4
__global__ void helloworld()
{
int x1,x2,x3,x4,x5,x6,x7,x8,rlow,rhgh;

rlow=-((gridDim.x-1)/2);
rhgh=((gridDim.x-1)/2);
x1=blockIdx.x+rlow;
x2=blockIdx.y+rlow;
x3=threadIdx.x+rlow;
x4=rlow;
x5=rlow;
x6=rlow;
x7=rlow;
x8=rlow;

while (x8<=rhgh)
{
if (x4 == x5)
{
if (x3 == -x8)
{
if (x4 + x7 == -x8)
{
if (x2+x4 == x6)
{
if (-2*( x4 + x6) + x8 == x1 + x2)
{
if (2*(x2+x4) + x1 + x5 == -3*x6)
{
printf("%+4d,%+4d,%+4d,%+4d,%+4d,%+4d,%+4d,%+4d \n", x1,x2,x3,x4,x5,x6,x7,x8);
}
}
}
}
}
}
x4=x4+1;
if (x4>rhgh)
{
x5=x5+1;
x4=rlow;
}
if (x5>rhgh)
{
x6=x6+1;
x5=rlow;
}
if (x6>rhgh)
{
x7=x7+1;
x6=rlow;
}
if (x7>rhgh)
{
x8=x8+1;
x7=rlow;
}
}
}

int main()
{
int rangeofsearch(searchsize);
dim3 grid,block;
grid.x=rangeofsearch;
grid.y=rangeofsearch;
block.x=rangeofsearch;
size_t buf=1e7;

cudaDeviceSetLimit(cudaLimitPrintfFifoSize, buf);
helloworld<<<grid,block>>>();
cudaDeviceSynchronize();
return 0;
}

Sample Output, powers in row form.

c0, h0, A0, R0, W0, G0, N0, F0

-14, -14, +0, +14, +14, +0, -14, +0
-13, -13, +0, +13, +13, +0, -13, +0
-12, -12, +0, +12, +12, +0, -12, +0
-11, -11, +0, +11, +11, +0, -11, +0
-7, -13, -2, +12, +12, -1, -14, +2
-6, -12, -2, +11, +11, -1, -13, +2
-5, -11, -2, +10, +10, -1, -12, +2
+0, -12, -4, +10, +10, -2, -14, +4
+1, -11, -4, +9, +9, -2, -13, +4
+7, -11, -6, +8, +8, -3, -14, +6
-14, -8, +2, +9, +9, +1, -7, -2
-13, -7, +2, +8, +8, +1, -6, -2
-12, -6, +2, +7, +7, +1, -5, -2
-11, -5, +2, +6, +6, +1, -4, -2 
...