用于有限元组装的CUDA内核

时间:2011-11-27 10:04:04

标签: assembly cuda element

我们有一个非结构化四面体网格文件,其中包含以下格式:

element-ID  nod1 nod2 nod3 nod4


    1            452  3434  322 9000

    2            2322   837 6673 2323

    .
    .
    .

300000

我们将上面的网格划分为每个2048的分区大小。 对于每个分区大小2048包含唯一的nod1 nod2 nod3 nod4值,我们在不同的起始索引处传递1个块和512个线程。

在cuda文件中,我们有

__global__ void calc(double d_ax,int *nod1,int *node2,int *nod3,int *nod4,int   start,int size)
{
    int n1,n2,n3,n4;     
    int i = blockIdx.x * blockDim.x + threadIdx.x + start;


    if ( i < size )
    {

        n1=nod1[i];
        n2=nod2[i];
        n3=nod3[i];
        n4=nod4[i];

        ax[n1] += some code;
        ax[n2] += some code;
        ax[n3] += some code;
        ax[n4] += some code;
    }
}

我们将内核称为

calc<<<1,512>>>(d_ax,....,0,512);
calc<<<1,512>>>(d_ax,....,512,512);
calc<<<1,512>>>(d_ax,....,1024,512); 
calc<<<1,512>>>(d_ax,....1536,512);

上面的代码效果很好,但问题是我们一次使用多个块得到不同的结果。例如:

calc<<<2,512>>>(d_ax,....,0,1024); 
calc<<<2,512>>>(d_ax,....,1024,1024); 

任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

我不确定您希望有人告诉您当您发布的代码不完整且无法编译时可能出现的问题,但 if 在您的单块情况下,您确实将内核称为内核你发布了,这是应该发生的事情:

calc<<<1,512>>>(d_ax,....,0,512);    // process first 512 elements
calc<<<1,512>>>(d_ax,....,512,512);  // start >= 512, size == 512, does nothing
calc<<<1,512>>>(d_ax,....,1024,512); // start >= 1024, size == 512, does nothing
calc<<<1,512>>>(d_ax,....1536,512);  // start >= 1536, size == 512, does nothing

因此,无论您的代码在使用多个块运行时是否可能被破坏,单个块情况的结果可能都是错误的,因此您的问题的重点可能无关紧要。

如果您想要更好的答案,请编辑您的问题,使其包含问题的完整描述以及可以实际编译的简洁,完整的代码。否则,这与任何人可以根据您提供的信息猜测的差不多。

答案 1 :(得分:0)

  

对于每个分区大小2048包含唯一的nod1 nod2 nod3 nod4   值

但是在两个分区集中可以出现相同的节点索引? 如果你有两个不同的区块

第1块: ax[1234]=do something

第2块: ax[1234]=do something else

它闻起来像一种竞争条件。你永远不知道两个块中的哪一个会更快写...