24小时热门版块排行榜    

查看: 306  |  回复: 0
当前主题已经存档。

js.ao

银虫 (正式写手)

[交流] 【转帖】如何把现有的有限元程序加入cuda支持以提高运算速度

有限元程序中,需要计算每个单元上的各个节点的内力分量,然后把这些节点力分量累加在一起。
比如,一个8节点长方体单元,可以计算出其8个节点的内力分量为
对每一个单元进行循环
LOOP KE=1 TO NELE
FORCE_ELE[1]=
FORCE_ELE[2]=
FORCE_ELE[3]=
....
FORCE_ELE[8]=

然后得到单元各个节点的编号
N1=NC[1][KE]
N2=NC[2][KE]
N3=NC[3][KE]
...
N8=NC[8][KE]

把这些力累加到节点上去
FORCE[N1]+=FORCE_ELE[1]
FORCE[N2]+=FORCE_ELE[2]
FORCE[N3]+=FORCE_ELE[3]
...
FORCE[N8]+=FORCE_ELE[8]

END LOOP

其中NC[ ]数组存储了网格的连接性, FORCE[ ]数组为gpu中全局数组。
因为单元网格是非结构化的,所以对于FORCE[ ]的读写就基本上是随机的(当然在执行效率上会非常差,这个以后再改进),所以在有多个BLOCK和THREAD的配置下执行时,应该会有同时读写同一块内存位置的时候。
当读FORCE的时候,CUDA能够保证其正确性,但是当写入时候,CUDA不能保证同时写入是否正确。
我也看了SKD中的histogram的例子,该例子通过用在每一个线程或wrap中分别存储结果后,然后再累加的方法解决了随机写会引起的冲突。
但是,在我的程序中,因为FORCE数组实在是太大,基本上应该在百万字节的大小,基本上不可能在每一个线程或wrap中分别全部存储。而且,实际上每个单元只有8个节点的数据需要更新,并没有必要分别每个线程或wrap中存储全部的FORCE数组。

这个问题,也许也有别人碰到过,请教有没有什么好地解决办法?


专家解答:
A:通过保留部分和再累加的方法避免写冲突的策略仍然是可行的。如果数据太多不能在shared memory中全部保存,一种简单的方法是launch多个kernel,在第一个kernel中进行局部数据更新(即更新FORCE_ELE),然后把所有局部数据写到global memory里;然后用另一个kernel来根据局部数据更新全局的FORCE。从算法看起来FORCE对FORCE_ELE累加的顺序并没有要求,所以用两个kernel是可能解决这个问题的。

我根据上面有限元的步骤,按照类似的步骤写了一段模拟程序如下,请帮我看看该如何解决,多谢

程序:
#include

#define BLOCK_NUM 3
#define THREAD_NUM 1

#define NUM_ELE 4
#define NUM_NOD 18

#define NC(j,N)  *(NC+(N-1)*8+j-1)
#define FORCE(N) *(FORCE+N-1)
//__global__ void init_force_kernel(float *);
__global__ void internal_kernel(int* , float *);

int main(void)
{

int NC[8*NUM_ELE];

float FORCE[18];

NC(1,1)=1  ;
NC(2,1)=3  ;
NC(3,1)=9  ;
NC(4,1)=7  ;
NC(5,1)=2  ;
NC(6,1)=4  ;
NC(7,1)=10 ;
NC(8,1)=8  ;

NC(1,2)=3  ;
NC(2,2)=5  ;
NC(3,2)=11 ;
NC(4,2)=9  ;
NC(5,2)=4  ;
NC(6,2)=6  ;
NC(7,2)=12 ;
NC(8,2)=10 ;

      NC(1,3)=7  ;
      NC(2,3)=9  ;
      NC(3,3)=15 ;
      NC(4,3)=13 ;
      NC(5,3)=8  ;
      NC(6,3)=10 ;
      NC(7,3)=16 ;
      NC(8,3)=14 ;

      NC(1,4)=9  ;
      NC(2,4)=11 ;
      NC(3,4)=17 ;
      NC(4,4)=15 ;
      NC(5,4)=10 ;
      NC(6,4)=12 ;
      NC(7,4)=18 ;
      NC(8,4)=16 ;

int *dNC;
float *dFORCE;

cudaMalloc( (void**)&dNC,NUM_ELE*8*sizeof(int));
cudaMalloc( (void**)&dFORCE,NUM_NOD*sizeof(float));

cudaMemcpy(dNC,NC,NUM_ELE*8*sizeof(int),cudaMemcpyHostToDevice);

// initialize the force first
cudaMemset(dFORCE,0.0,NUM_NOD*sizeof(float));

internal_kernel < < >>(dNC,dFORCE);

cudaMemcpy(FORCE,dFORCE,NUM_NOD*sizeof(float),cudaMemcpyDeviceToHost);

for(int i=1;i <=NUM_NOD;i++)
printf("NOD %d %f\n",i,FORCE(i));

    cudaFree(dNC);
cudaFree(dFORCE);
return 0;

}

__global__ void internal_kernel(int* NC, float *FORCE)
{
const int tid=threadIdx.x;
const int bid= blockIdx.x;

const int THREADS=blockDim.x;
const int BLOCKS=gridDim.x;

float FORCE_ELE[8];

//compute internal force
for(int NELE=bid*THREADS+tid+1;NELE <=NUM_ELE;NELE+=BLOCKS*THREADS)
{
for(int j=1;j <=8;j++)
FORCE_ELE[j-1]=NELE*10.0+j*1.0;

for(int j=1;j <=8;j++)
{
int NOD;
NOD=NC(j,NELE);
FORCE(NOD)+=FORCE_ELE[j-1];
// printf("NELE: %1d  J:%1d  NOD:%2d \t FORCE_ELE:%10.1f\t FORCE:%10.1f\n",NELE,j,NOD,FORCE_ELE[j-1],FORCE(NOD));
}

}

return ;

}
回复此楼
爱是一道光,如此美妙
已阅   回复此楼   关注TA 给TA发消息 送TA红花 TA的回帖
相关版块跳转 我要订阅楼主 js.ao 的主题更新
普通表情 高级回复 (可上传附件)
最具人气热帖推荐 [查看全部] 作者 回/看 最后发表
[基金申请] 什么时候开奖? +4 CrisMessi 2026-08-18 4/200 2026-08-19 00:53 by gatelove
[教师之家] 为什么余额宝的年化利率越来越低?主要原因有哪些? +3 瞬息宇宙 2026-08-15 3/150 2026-08-18 21:40 by xiaohuixin
[基金申请] 2027广东省杰青 +3 奶牛小黑 2026-08-15 9/450 2026-08-18 20:09 by 奶牛小黑
[基金申请] 朋友圈看到的 +4 wangzilk 2026-08-18 5/250 2026-08-18 19:25 by wangzilk
[基金申请] 欢迎发来filecode的Mz6后的代码验证其规律 +51 医学老男孩 2026-08-13 110/5500 2026-08-18 19:07 by icerianxia
[基金申请] 明天放榜? +5 Shxjjxjkx 2026-08-18 5/250 2026-08-18 18:14 by -大大大大大-
[基金申请] 时间戳变了,能看出什么问题? +8 基诺咪客 2026-08-17 11/550 2026-08-18 17:13 by 悠然熊猫
[基金申请] 重要消息,中午系统在维护 +9 yuleib84 2026-08-18 10/500 2026-08-18 16:52 by archvillain
[论文投稿] 投稿咨询 +4 wwm09 2026-08-17 6/300 2026-08-18 15:36 by wwm09
[基金申请] 时间戳又变了8-15 +14 archvillain 2026-08-15 26/1300 2026-08-18 13:37 by phantomgost
[基金申请] 今天维护系统维护 祝所有人 高中 +8 gjjjzhong 2026-08-18 9/450 2026-08-18 13:01 by 家与远方
[基金申请] 哪位老哥知道今年的国自然具体哪一天放榜? +13 Ldrop2023 2026-08-13 16/800 2026-08-18 12:25 by 淀粉搬运工
[基金申请] 快农历七夕节了,轻松一下,男人悄悄话,女施主请不要进来。 +4 Tide man 2026-08-14 5/250 2026-08-18 11:35 by Tide man
[基金申请] 93BebMhtakh前后11位开头都是大写 +4 且听虎啸 2026-08-17 5/250 2026-08-18 00:49 by 蔡棒棒菂
[基金申请] 感觉是下周放榜了 +6 angus9576 2026-08-17 11/550 2026-08-17 23:57 by angus9576
[基金申请] filecode=后面第一个是大写字母 +8 wangze12014 2026-08-14 10/500 2026-08-17 17:05 by xter9665
[基金申请] 今天系统多次维护,明天很可能放榜! +8 zju2000 2026-08-16 9/450 2026-08-17 12:20 by lmz0216
[基金申请] 重要来源:本周末出结果 +10 瞬息宇宙 2026-08-12 10/500 2026-08-13 15:46 by likettle
[基金申请] Filecode 又变了,巨变 +3 WH3796 2026-08-12 4/200 2026-08-13 14:13 by 小木虫6752397
[基金申请] 结合人工智能,周易传统文化,filecode打分制来了,3分以上希望很大。 +3 Tide man 2026-08-12 4/200 2026-08-13 08:35 by ZJTJZ
信息提示
请填处理意见