Visual studio 2008 内联ptx中的加载函数参数

Visual studio 2008 内联ptx中的加载函数参数,visual-studio-2008,cuda,ptx,Visual Studio 2008,Cuda,Ptx,在32位Visual Studio 2008中,我有以下内联汇编函数,可以在调试模式下正常工作: __device__ void add(int* pa, int* pb) { asm(".reg .u32 s<3>;"::); asm(".reg .u32 r<14>;"::); asm("ld.global.b32 s0, [%0];"::"r"(&pa)); //load addresses of pa, pb pr

在32位Visual Studio 2008中,我有以下内联汇编函数,可以在调试模式下正常工作:

__device__ void add(int* pa, int* pb)
{
  asm(".reg .u32   s<3>;"::);
  asm(".reg .u32   r<14>;"::);

  asm("ld.global.b32    s0, [%0];"::"r"(&pa));      //load addresses of pa, pb
  printf(...);
  asm("ld.global.b32    s1, [%0];"::"r"(&pb));
  printf(...);
  asm("ld.global.b32    r1, [s0+8];"::);
  printf(...);  
  asm("ld.global.b32    r2, [s1+8];"::);
  printf(...);

  ...// perform some operations
}
但是,该代码在发布模式下失败,在asm(“ld.global.b32 r1,[s0+8];”:)线上 如何在释放模式下使用内联ptx正确加载功能参数

另外,使用-G标志构建发布模式(生成GPU调试信息)会导致代码在发布模式下正确运行。
谢谢,

希望这段代码能有所帮助。我仍然在猜测你到底想做什么,但我从你的代码开始,决定在
pa
pb
数组中添加一些值,并将它们存储回
pa[0]
pb[0]

此代码是为64位机器编写的,但将其转换为32位指针应该并不困难。我已经用注释标记了32位指针需要更改的行。希望这能回答您关于如何使用指向设备内存的函数参数的问题:

#include <stdio.h>

__device__ int pa[3] = {0, 0x927c0000, 0x20000011};
__device__ int pb[3] = {0, 0xbb900000, 0x2000000b};

__device__ void add(int* mpa, int* mpb)
{
  asm(".reg .u64   s<2>;"::);  // change to .u32 for 32 bit pointers
  asm(".reg .u32   r<6>;"::);

  asm("mov.u64    s0, %0;"::"l"(mpa));      //change to .u32 and "r" for 32 bit
  asm("mov.u64    s1, %0;"::"l"(mpb));      //change to .u32 and "r" for 32 bit
  asm("ld.global.u32    r0, [s0+4];"::);
  asm("ld.global.u32    r1, [s1+4];"::);
  asm("ld.global.u32    r2, [s0+8];"::);
  asm("ld.global.u32    r3, [s1+8];"::);
  asm("add.u32    r4, r0, r2;"::);
  asm("add.u32    r5, r1, r3;"::);
  asm("st.global.u32    [s0], r4;"::);
  asm("st.global.u32   [s1], r5;"::);
}

__global__ void mykernel(){
  printf("pa[0] = %x, pb[0] = %x\n", pa[0], pb[0]);
  add(pa, pb);
  printf("pa[0] = %x, pb[0] = %x\n", pa[0], pb[0]);
}

int  main() {
  mykernel<<<1,1>>>();
  cudaDeviceSynchronize();
  return 0;
}
我认为这是正确的输出

我是用以下方法编写的:

nvcc -O3 -arch=sm_20 -o t128 t128.cu

您的发布版本也是32位的吗?否则,线路将明显故障。如果没有:如果您告诉我们错误消息是什么,则可以更容易地帮助处理错误消息。实体
pa
可能在释放模式下优化到寄存器中,并且您不能获取寄存器的地址。那只是猜测。如果您定义了所观察到的故障是在编译时还是在运行时,这将非常有用。如果在编译时,您会得到什么错误?如果在运行时,您是如何本地化到这行代码的?您为什么要使用
pa
的地址?获取函数参数的地址似乎很奇怪。要在调用上下文中修改pa,您需要传递一个指向它的指针,即
**pa
您的意思是
*pa
还是
&(pa[0])
pa
?@tera:Release build也是32位的。发布版本编译时没有任何错误。当我运行时,我得到不同的输出。此外,我在每个ld.global.b32指令后都有printf语句。它在asm之后失败(“ld.global.b32 r1,[s0+8];”:);这样它就不会打印下一个printf语句。正如Robert所说,获取函数指针的地址是很奇怪的。为什么不移动参数本身:
asm(“mov.b32 s0,%0;”:“r”(pa))?@RobertCrovella:错误发生在运行时。我得到了完全错误的输出;asm之后的printf和其他说明(“ld.global.b32 r1,[s0+8];”:);没有执行,它们被跳过,然后程序以错误的输出退出。
$ ./t128
pa[0] = 0, pb[0] = 0
pa[0] = b27c0011, pb[0] = db90000b
$
nvcc -O3 -arch=sm_20 -o t128 t128.cu