我想在CUDA PTX中添加兩個32位無符號整數,並且我也希望處理進位傳播。我使用下面的代碼來做到這一點,但結果並不如預期。
根據documentation,add.cc.u32 d, a, b
執行整數加法並將進位值寫入條件碼寄存器,即CC.CF
。
另一方面,addc.cc.u32 d, a, b
通過進位進行整數加法運算,並將進位值寫入條件碼寄存器。這條指令的語義是
d = a + b + CC.CF
。我也嘗試了addc.u32 d, a, b
沒有區別。CUDA - PTX進行傳播
#include <stdio.h>
#include <stdlib.h>
#include <cuda_runtime_api.h>
#include "device_launch_parameters.h"
#include <cuda.h>
typedef unsigned int u32;
#define TRY_CUDA_CALL(x) \
do \
{ \
cudaError_t err; \
err = x; \
if(err != cudaSuccess) \
{ \
printf("Error %08X: %s at %s in line %d\n", err, cudaGetErrorString(err), __FILE__, __LINE__); \
exit(err); \
} \
} while(0)
__device__ u32
__uaddo(u32 a, u32 b) {
u32 res;
asm("add.cc.u32 %0, %1, %2; /* inline */ \n\t"
: "=r" (res) : "r" (a) , "r" (b));
return res;
}
__device__ u32
__uaddc(u32 a, u32 b) {
u32 res;
asm("addc.cc.u32 %0, %1, %2; /* inline */ \n\t"
: "=r" (res) : "r" (a) , "r" (b));
return res;
}
__global__ void testing(u32* s)
{
u32 a, b;
a = 0xffffffff;
b = 0x2;
s[0] = __uaddo(a,b);
s[0] = __uaddc(0,0);
}
int main()
{
u32 *s_dev;
u32 *s;
s = (u32*)malloc(sizeof(u32));
TRY_CUDA_CALL(cudaMalloc((void**)&s_dev, sizeof(u32)));
testing<<<1,1>>>(s_dev);
TRY_CUDA_CALL(cudaMemcpy(s, s_dev, sizeof(u32), cudaMemcpyDeviceToHost));
printf("s = %d;\n",s[0]);
return 1;
}
據我所知,你會得到一個進位,如果結果不變量,它在這裏發生,如果符號位被損壞的溢出放進去,但我與無符號值工作。
上面的代碼嘗試將0xFFFFFFFF
添加到0x2
,當然結果將不適合32位,所以爲什麼我在調用__uaddc(0,0)
後沒有得到1?
編輯
的NVIDIA GeForce GT 520mx
Windows 7旗艦版,64位
的Visual Studio 2012
CUDA 7.0
請參閱[本答案](http://stackoverflow.com/a/6220499/780717)瞭解如何在PTX中使用進位傳播進行多字算法的工作示例。 – njuffa
我從你的答案中使用了'add_uint128',進位傳播正在進行,但是我的問題出了什麼問題?成功的'add.cc.u32'和'addc.cc.u32'與我所看到的一樣。 –
成功是一樣的,但我使用不同的調用。我認爲註冊'CC.CF'不應該改變。 –