关于CUDA上的整数加法问题

各位好,本人现在正在利用cuda写一个密码算法,其中涉及到cuda 32bit加法进位的问题。
如果采用
temp = a;
a = a + b;
carry = a < temp;
这种写法,比较操作将会占用大量时间。我自己编写的64bit乘法包括8次乘法,4次比较和两次加法,估算速度是每周期2.8次。 把进位比较的部分改成
temp = a;
a = a + b;
carry = 1;
速度是每周期3.8次,差距巨大。我用的是GTX 680,查看手册发现整形乘法每个周期32次,加法、比较操作160次。只差了4次比较,差距接近33%,有点不科学啊。
我的问题是(1)整数比较真的这么费时间吗? (2)还有就是cuda中是否有一个进位寄存器,能不能通过直接调用类似于ADC的加法,进行进位加法。谢谢!

看了下汇编代码,这一句比较貌似被汇编成一串比较长的代码,有没有办法直接进行比较呢?

楼主您好,

(1)如果需要使用64位整数加法,请直接#include<stdint.h>后:
int64_t a;
int64_t b;
int64_t c = a + b;
来做加法。此时将自动利用硬件支持的进位加法,而无需你手工判断进位(进位将在低32位做加法的时候,自动判断产生)。

(2)如果您坚持手工进行64位加法,同时需要使用进位标志寄存器,那么您只能使用嵌入式PTX汇编(只有这样才能利用上免费的进位标志和带进位加法指令)。

下文为您演示了如何利用硬件的进位标志寄存器,以及演示如何使用进位加法指令:
int a1,a0;
int b1,b0;
int c1,c0;
asm volatile
(“add.cc.s32 %0, %2, %3;”
“addc.s32 %1, %4, %5;”
:“=r”(c0),“=r”(c1)
:“r”(a0),“r”(b0),“r”(a1),“r”(b1)
);

上文的:
(1)add.cc指令将执行普通加法,并设置标志寄存器中的进位标志。
(2)addc指令将执行带有进位标志参与的加法。

PS: 楼主您实际想进行64-bit整数乘法,请您直接提出。别拐弯抹角。
PS:因为您的标题和内容不符合,您文章的矛盾处是以您的标题为准的。

感谢您莅临CUDAZone China

版主您好,非常感谢!再麻烦您一下,乘加指令是否可能类似的设定寄存器中的进位标志呢?

楼主您好,

可以设置使用标志寄存器的CF位的。

以下代码给出了示意(请注意仅为示意,不保证完全正确):

uint32_t a1,a0; //64位被乘数
uint32_t b1,b0; //64位乘数
uint32_t c3,c2,c1,c0; //128-bit积

asm volatile
(“mul.lo.u32 %0,%4,%6;”
“mul.hi.u32 %1,%4,%6;” //分2次计算a0 * b0, 64位乘法
“mad.lo.cc.u32 %1,%5,%6,%1;”
“madc.hi.u32 %2,%5,%6,0;” //分2次计算a1 * b0, 并累加上次结果
“mad.lo.cc.u32 %1,%4,%7,%1;”
“madc.hi.cc.u32 %2,%4,%7,%2;”
“addc.u32 %3,0,0;” //分2次计算a0 * b1, 累加结果和进位
“mad.lo.cc.u32 %2,%5,%7,%2;”
“madc.hi.u32 %3,%5,%7,%3;” //a1 * b1, 并累加结果
:“=r”(c0),“=r”(c1),“=r”(c2),“=r”(c3)
:“r”(a0),“r”(a1),“r”(b0),“r”(b1)
);

非常感谢!实在是太有帮助了!