CUDA - 大数和内存分配

时间:2015-04-13 13:52:54

标签: c cuda nvcc unsigned-long-long-int

程序中有一个非常奇怪的错误。我花了很多时间,但我没有找到解决方案。我写了一个简单的程序来重现我的问题。也许有人帮助我。我试过cuda-memcheck& What is the canonical way to check for errors using the CUDA runtime API?但我没有收到任何错误。

详细说明:

nvcc版本 - V6.0.1

gcc版本 - 4.8.1

完整代码:

#include <stdio.h>

__constant__ unsigned long long int bigNumber = 83934243334343;
__device__ bool isFound = false;
__global__ void kernel(int *dev_number) {

    unsigned long long int id = threadIdx.x + (blockIdx.x * blockDim.x);
    while (id < bigNumber && isFound==false) {

        if(id == 10) {
            *dev_number = 4;
            isFound=true;
        }
        id++;
    }
}

int main(int argc, char *argv[]) {
    int number = 0;
    int *dev_number;

    printf("Number: %d\n", number);

    return 0;
}

编译并运行:

nvcc myprogram.cu
./myprogram

当我运行此程序时,我没有获得任何返回值。但是当变量 - bigNumber值较小或者我不使用cudaMalloc&amp; cudaMemcpy它工作(它意味着返回0被调用)。什么连接必须为具有常量bigNumber的另一个变量分配内存?问题是什么?

1 个答案:

答案 0 :(得分:1)

既然您已将代码修改为更合理的代码,我会立即得到以下修改结果:

__device__ volatile bool isFound = false;

volatile限定符强制编译器省略任何阻止每个线程读取变量的全局副本的优化。

来自documentation

  

编译器可以自由优化对全局或共享内存的读写操作(例如,通过将全局读取缓存到寄存器或L1缓存中),只要它遵守内存栅栏函数(内存栅栏函数)的内存排序语义和同步函数的内存可见性语义(同步函数)。

     

可以使用volatile关键字禁用这些优化:如果位于全局或共享内存中的变量声明为volatile,则编译器假定其值可以随时由另一个线程更改或使用,因此对此的任何引用变量编译为实际的内存读或写指令。

如果您未能使用volatile限定符,则只有一个线程采用提前退出条件(isFound),其他所有线程必须循环很长时间直到他们的id值超过bigNumber