Cuda PTX ISA中的错误(进位传播)?

Cuda PTX ISA中的错误(进位传播)?,cuda,ptx,Cuda,Ptx,Cuda有臭虫吗?我已经在我的GTX580上运行了以下代码,最后r1为零。我认为这是一个由于进行传播?我已经使用Cuda Toolkit 4.2.9和5.5测试了代码,并使用“nvcc-arch=sm_20 bug.cu-o bug&&./bug”编译和运行它 #include <stdio.h> #include <cuda.h> __global__ void bug() { unsigned int r1 = 0; unsigned int r2 = 0;

Cuda有臭虫吗?我已经在我的GTX580上运行了以下代码,最后r1为零。我认为这是一个由于进行传播?我已经使用Cuda Toolkit 4.2.9和5.5测试了代码,并使用“nvcc-arch=sm_20 bug.cu-o bug&&./bug”编译和运行它

#include <stdio.h>
#include <cuda.h>

__global__ void bug()
{
  unsigned int r1 = 0;
  unsigned int r2 = 0;

  asm( "\n\t"
       "sub.cc.u32 %0, 0, 1;\n\t"
       "addc.cc.u32 %1, 0, 0;\n\t"
     : "=r"(r1), "=r"(r2) );

  printf("r1 >> %04X\n", r1);
  printf("r2 >> %04X\n", r2);

}

int main(void)
{
  float *a_d;
  cudaMalloc((void **) &a_d, 1);

  bug <<< 1,1 >>> ();

  cudaFree(a_d);
}

Output
r1 >> FFFFFFFF
r2 >> 0000
#包括
#包括
__全局无效错误()
{
无符号整数r1=0;
无符号整数r2=0;
asm(“\n\t”
sub.cc.u32%0,0,1;\n\t
addc.cc.u32%1,0,0;\n\t
:“=r”(r1),“=r”(r2));
printf(“r1>>%04X\n”,r1);
printf(“r2>>%04X\n”,r2);
}
内部主(空)
{
浮动*a_d;
Cudamaloc((无效**)和a_d,1);
bug>();
cudaFree(a_d);
}
输出
r1>>FFFFFFFF
r2>>0000

我相信您对中引用的
CC.CF
标志做出了一些可能无效的假设

请注意,我看不到该位的特定状态(例如0或1)的定义。此外,我没有发现“进货/进货”和“借进/借出”的定义之间有任何对应关系

换句话说,我认为您假设此标志中的“借用”状态与“携带”状态相同。换句话说,您假设的是:

CF:  
0    =  (NO CARRY) or (NO BORROW)
1    =  (CARRY) or (BORROW)
但这样的真值表或映射从未给出。此外,手册规定:

条件代码寄存器。。。主要用于计算扩展精度整数加法、减法和乘法的直线代码序列

我认为您的代码不符合目的,我也不认为上面关于
CC.CF
的真值表的假设是有效的

事实上,我认为正在发生的是这样一个真值表:

CF:  
0    =  (CARRY) or (NO BORROW)
1    =  (NO CARRY) or (BORROW)
(此处的0和1是任意的;手册中也没有定义。)

我尝试过的所有代码示例(大约6个,包括您的)都符合我上面给出的定义


话虽如此,我认为依靠这一点是不明智的,因为它大多没有文件记录。计算机体系结构的一个安全规则是,未记录的行为将来可能会改变。

我想我已经找到了一个解释。PTX手册中有一条关于sub.cc指令的说明:“无符号整数和有符号整数的行为相同。”

您使用的是windows还是linux?当我编译并运行您的代码时,我得到了相反的结果,即
r1>>ffffff
r2>>0000
如果您提供一个完整的、可编译的代码,以及用于构建它的编译命令,可能会更好。哦,该死的,您是对的。我已经更正了我的代码。但是在你的机器上r2=0而不是r2=1?很奇怪。怎么可能呢?我正在使用Ubuntu 12.04。@Crovella:我创建了一个小的示例程序。我使用“nvcc-arch=sm_20 bug.cu-o bug&&./bug”来编译和运行它。您想运行这个特定序列的原因是什么?进位指令主要用于扩展精度整数运算,即加法序列、减法序列或乘法序列。如果我将您的代码转换为减法序列(例如,将addc指令转换为
subc.u32%1,1,0;
),我将得到预期的结果(r2为0).您所显示的代码有什么特殊用途吗?您可能应该使用与您发出的上一条进位算术指令相匹配的指令进行检查。因此,如果上一条指令是减法指令,请使用减法来检查借位。如果上一条指令是加法指令,请使用加法来检查进位。我不确定您为什么这样认为s会解释的。试试这一系列说明,看看你的答案是否解释了结果。然后看看我的答案是否解释了结果:
sub.cc.u32%0,0,0;
addc.cc.u32%1,0,0;