gpt4 book ai didi

integer - cuda上的128位整数?

转载 作者:行者123 更新时间:2023-11-30 17:01:53 29 4
gpt4 key购买 nike

我刚刚成功在 Linux Ubuntu 10.04 下安装了我的 cuda SDK。我的显卡是 NVIDIA geForce GT 425M,我想用它来解决一些繁重的计算问题。我想知道的是:有没有办法使用一些无符号的 128 位 int var?当使用 gcc 在 CPU 上运行我的程序时,我使用的是 __uint128_t 类型,但将它与 cuda 一起使用似乎不起作用。我可以做些什么来在 cuda 上拥有 128 位整数吗?

最佳答案

为了获得最佳性能,人们希望将 128 位类型映射到合适的 CUDA 向量类型(例如 uint4)之上,并使用 PTX 内联汇编来实现功能。添加内容看起来像这样:

typedef uint4 my_uint128_t;
__device__ my_uint128_t add_uint128 (my_uint128_t addend, my_uint128_t augend)
{
my_uint128_t res;
asm ("add.cc.u32 %0, %4, %8;\n\t"
"addc.cc.u32 %1, %5, %9;\n\t"
"addc.cc.u32 %2, %6, %10;\n\t"
"addc.u32 %3, %7, %11;\n\t"
: "=r"(res.x), "=r"(res.y), "=r"(res.z), "=r"(res.w)
: "r"(addend.x), "r"(addend.y), "r"(addend.z), "r"(addend.w),
"r"(augend.x), "r"(augend.y), "r"(augend.z), "r"(augend.w));
return res;
}

可以使用 PTX 内联汇编类似地构建乘法,方法是将 128 位数字分解为 32 位 block ,计算 64 位部分积并适本地将它们相加。显然这需要一些工作。通过将数字分解为 64 位 block 并使用 __umul64hi() 与常规 64 位乘法和一些加法结合使用,可以在 C 级别获得合理的性能。这将导致以下结果:

__device__ my_uint128_t mul_uint128 (my_uint128_t multiplicand, 
my_uint128_t multiplier)
{
my_uint128_t res;
unsigned long long ahi, alo, bhi, blo, phi, plo;
alo = ((unsigned long long)multiplicand.y << 32) | multiplicand.x;
ahi = ((unsigned long long)multiplicand.w << 32) | multiplicand.z;
blo = ((unsigned long long)multiplier.y << 32) | multiplier.x;
bhi = ((unsigned long long)multiplier.w << 32) | multiplier.z;
plo = alo * blo;
phi = __umul64hi (alo, blo) + alo * bhi + ahi * blo;
res.x = (unsigned int)(plo & 0xffffffff);
res.y = (unsigned int)(plo >> 32);
res.z = (unsigned int)(phi & 0xffffffff);
res.w = (unsigned int)(phi >> 32);
return res;
}

下面是使用 PTX 内联汇编的 128 位乘法的版本。它需要 PTX 3.0(随 CUDA 4.2 一起提供),并且代码需要至少具有计算能力 2.0 的 GPU,即 Fermi 或 Kepler 类设备。该代码使用最少数量的指令,因为需要 16 个 32 位乘法来实现 128 位乘法。相比之下,上面使用 CUDA 内在函数的变体为 sm_20 目标编译为 23 条指令。

__device__ my_uint128_t mul_uint128 (my_uint128_t a, my_uint128_t b)
{
my_uint128_t res;
asm ("{\n\t"
"mul.lo.u32 %0, %4, %8; \n\t"
"mul.hi.u32 %1, %4, %8; \n\t"
"mad.lo.cc.u32 %1, %4, %9, %1;\n\t"
"madc.hi.u32 %2, %4, %9, 0;\n\t"
"mad.lo.cc.u32 %1, %5, %8, %1;\n\t"
"madc.hi.cc.u32 %2, %5, %8, %2;\n\t"
"madc.hi.u32 %3, %4,%10, 0;\n\t"
"mad.lo.cc.u32 %2, %4,%10, %2;\n\t"
"madc.hi.u32 %3, %5, %9, %3;\n\t"
"mad.lo.cc.u32 %2, %5, %9, %2;\n\t"
"madc.hi.u32 %3, %6, %8, %3;\n\t"
"mad.lo.cc.u32 %2, %6, %8, %2;\n\t"
"madc.lo.u32 %3, %4,%11, %3;\n\t"
"mad.lo.u32 %3, %5,%10, %3;\n\t"
"mad.lo.u32 %3, %6, %9, %3;\n\t"
"mad.lo.u32 %3, %7, %8, %3;\n\t"
"}"
: "=r"(res.x), "=r"(res.y), "=r"(res.z), "=r"(res.w)
: "r"(a.x), "r"(a.y), "r"(a.z), "r"(a.w),
"r"(b.x), "r"(b.y), "r"(b.z), "r"(b.w));
return res;
}

关于integer - cuda上的128位整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36791524/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com