Cuda有符号128位乘法错误

Cuda有符号128位乘法错误,cuda,ptx,Cuda,Ptx,我想我在cuda PTX中使用有符号整数进行128位有符号乘法时发现了一个问题。 以下是我的示例代码: long long result_lo, result_hi; asm(" mul.lo.s64 %0, 0, -1; \n\t" // 0 * -1 = 0 " mul.hi.s64 %1, 0, -1; \n\t" : "=l"(result_lo), "=l"(result_hi)); 这将产生结果result\u lo=0x0,result\u hi=

我想我在cuda PTX中使用有符号整数进行128位有符号乘法时发现了一个问题。 以下是我的示例代码:

long long result_lo, result_hi;
asm(" mul.lo.s64 %0, 0, -1;     \n\t" // 0 * -1 = 0
    " mul.hi.s64 %1, 0, -1;     \n\t"
    : "=l"(result_lo), "=l"(result_hi));
这将产生结果
result\u lo=0x0,result\u hi=0x0
。但是,这会产生结果:
result\u lo=0x0,result\u hi=0xffffffffffff
,如果我没有弄错并且显然不是零,那么它实际上就是值
2^127-(2^126-1)

首先,我想确保我的理解是正确的,但更重要的是,有办法解决这个问题吗

更新
Debug
mod更改为
Release
模式修复了此问题,仍不知道这是否是cuda中的错误

更新2 已向NVIDIA报告此错误


在Visual Studio 2013中使用Cuda toolkit 7.5
x64调试
sm_52
compute_52
TL;DR这似乎是针对
sm_5x
平台的PTX指令
mul.hi.s64
仿真中的一个错误,因此建议向NVIDIA提交错误报告

通常,NVIDIA GPU是32位体系结构,因此所有64位整数指令都需要仿真序列。在64位整数乘法的特殊情况下,对于
sm_2x
sm_3x
平台,它们是由机器码指令
IMAD.U32
构成的,这是一条32位整数乘法加法指令

对于Maxwell体系结构(即,
sm_5x
),引入了高吞吐量但较低宽度的整数乘法加法指令
XMAD
,但显然保留了低吞吐量的传统32位整数乘法
IMUL
。通过CUDA 7.5工具链使用
cuobjdump--dumpsass
检查为
sm5x
生成的反汇编机器代码显示,对于
ptxas
优化级别
-O0
(用于调试构建),使用
IMUL
指令模拟64位乘法,而对于优化级别
-O1
和更高级别
XMAD
。我想不出为什么要使用两种根本不同的仿真序列

事实证明,基于
sm_5x
mul.hi.s64
的基于
IMUL
的仿真被破坏,而基于
XMAD
的仿真工作正常。因此,一种可能的解决方法是通过在
nvcc
命令行上指定
-Xptxas-O1
来为
ptxas
使用至少
-O1
的优化级别。请注意,默认情况下,发布版本使用
-Xptxas-O3
,因此无需对发布版本执行任何纠正操作

从代码分析来看,
mul.hi.s64
的仿真是作为
mul.hi.u64
仿真的包装器实现的,后面的仿真似乎可以在所有平台上正常工作,包括
sm_5x
。因此,另一种可能的解决方法是使用我们自己的包装器来包装mul.hi.u64。在这种情况下,使用内联PTX编码是不必要的,因为
mul.hi.s64
mul.hi.u64
可以通过设备内部函数
\uu mul64hi()
访问。从下面的代码可以看出,将结果从无符号乘法转换为有符号乘法的调整相当简单

长整型m1,m2,结果;
#如果0//在优化级别的sm_5x上损坏-O0
asm(“mul.hi.s64%0,%1,%2;\n\t”
:“=l”(结果)
:“l”(m1),“l”(m2));
#否则
结果=uuuumul64hi(m1,m2);
如果(m1<0LL)结果-=m2;
如果(m2<0LL)结果-=m1;
#恩迪夫

TL;DR这似乎是针对
sm_5x
平台的PTX指令
mul.hi.s64
仿真中的一个错误,因此建议向NVIDIA提交错误报告

通常,NVIDIA GPU是32位体系结构,因此所有64位整数指令都需要仿真序列。在64位整数乘法的特殊情况下,对于
sm_2x
sm_3x
平台,它们是由机器码指令
IMAD.U32
构成的,这是一条32位整数乘法加法指令

对于Maxwell体系结构(即,
sm_5x
),引入了高吞吐量但较低宽度的整数乘法加法指令
XMAD
,但显然保留了低吞吐量的传统32位整数乘法
IMUL
。通过CUDA 7.5工具链使用
cuobjdump--dumpsass
检查为
sm5x
生成的反汇编机器代码显示,对于
ptxas
优化级别
-O0
(用于调试构建),使用
IMUL
指令模拟64位乘法,而对于优化级别
-O1
和更高级别
XMAD
。我想不出为什么要使用两种根本不同的仿真序列

事实证明,基于
sm_5x
mul.hi.s64
的基于
IMUL
的仿真被破坏,而基于
XMAD
的仿真工作正常。因此,一种可能的解决方法是通过在
nvcc
命令行上指定
-Xptxas-O1
来为
ptxas
使用至少
-O1
的优化级别。请注意,默认情况下,发布版本使用
-Xptxas-O3
,因此无需对发布版本执行任何纠正操作

从代码分析来看,
mul.hi.s64
的仿真是作为
mul.hi.u64
仿真的包装器实现的,后面的仿真似乎可以在所有平台上正常工作,包括
sm_5x
。因此,另一种可能的解决方法是使用我们自己的包装器来包装mul.hi.u64。在这种情况下,使用内联PTX编码是不必要的,si