旧显示驱动程序上的奇怪CUDA内核结果

时间:2015-12-07 09:46:35

标签: c++ cuda

我正在编写一个可以在数千个不同的GPU上运行的CUDA程序,这些机器将安装不同版本的显示驱动程序,我不能强制它们更新到最新的驱动程序。实际上大多数代码在那些“旧”机器上运行正常,但是在某些特定代码中失败了:

问题在于:

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

__global__
void test()
{
    unsigned i = 64;
    unsigned j = 192;
    int k = 7;

    for(j = 1 << (k - 1); i &j; j >>= 1)
        i ^= j;
    i ^= j;

    printf("i,j,k: %d,%d,%d\n", i,j,k);
    // i,j,k: 32,32, 7  (correct)
    // i,j,k: 0, 64, 7  (wrong)
}

int main() {
    cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync);

    test<<<1,1>>>();
}

代码在GPU上使用最新的驱动程序打印32,32,7,这是正确的结果。但是在旧驱动程序(低于CUDA 6.5 )上,它会打印0,64,7

我正在寻找任何解决方法。

Envoronment:

  1. 开发:Win7-32​​bit,VS2013,CUDA 6.5
  2. Corrent结果:WinXP-32bit(和Win7-32​​bit),GTX-650(最新驱动程序)
  3. 错误的结果:WinXP-32bit + GTX-750-Ti(旧驱动程序),WinXP-32bit + GTX-750(旧驱动程序)

2 个答案:

答案 0 :(得分:2)

没有解决方法。运行时API已版本化,并且最低驱动程序版本要求是不可协商的。

您唯一的两个选择是使用支持所使用的驱动程序的最低公分母工具包版本进行开发,或者切换到驱动程序API。

答案 1 :(得分:0)

得到一个非常慢的解决方案:使用本地内存而不是寄存器变量。 只需在i,j

之前添加 volatile 关键字
volatile unsigned i = 64;
volatile unsigned j = 192;