【问题标题】:simultaneous calling of same cuda functions on multiple GPUs using independent streams使用独立流在多个 GPU 上同时调用相同的 cuda 函数
【发布时间】:2012-07-16 11:13:46
【问题描述】:

我正在多个 GPU 上实现我的程序... 我的 PC 中有两个 GPU,想生成两个独立的流来处理这两个设备。我生成了两个流:

cudaStream_t *streams; 
streams = (cudaStream_t*) malloc(nstreams * sizeof(cudaStream_t));
for(int j = 0; j < nstreams; j++){
    cudaStreamCreate(&(streams[j]));
}

然后,根据 SDK 示例,我尝试使用设备 ID 作为参数调用内核。 根据设备 id 设置 cudaDevice (cudaSetDevice(dev_ID);) 并通过各自的流传递内核调用:

kernel1<<< grid, block,0,streamNo >>>(tex, size);................


for (i = 0;i<gpuN;i++){
    initialize(i);
    printf("initialization done with stream %i on device %i\n", (int)streams[i], i);
    runTest(i);
    printf("running tests done with  %i  stream \n", i);
    deini(i);
    printf("deinitialization is done\n");
}

我的程序在两个不同的流中运行良好,但它是按顺序运行的。 我想使用两个设备同时使用两个独立的流来运行功能。谁能帮我解决这个问题?

我正在使用两个 Tesla 2070 处理 CUDA 4.2。

【问题讨论】:

    标签: cuda


    【解决方案1】:

    您创建的流与您创建它们的上下文相关联,在创建流的上下文之外的任何上下文中使用流都是非法的。在 CUDA 4.x 及更高版本中,使用cudaSetDevice() 执行上下文切换。

    因此,为了做到这一点,您需要执行以下操作:

    cudaStream_t *streams[ndevices];
    
    for(int i=0; i<ndevices; i++) {
        cudaSetDevice(i);  
        streams[i] = (cudaStream_t*) malloc(nstreams * sizeof(cudaStream_t)); 
        for(int j = 0; j < nstreams; j++){ 
            cudaStreamCreate(&(streams[j])); 
        }
    } 
    

    这将在枚举[0,..,ndevices-1] 的每个设备上创建nstreams 流。每当对流执行操作(启动内核、执行异步 memcpy 等)时,您必须首先对正确的设备上下文执行 cudaSetDevice()

    听起来您可能根本不需要使用流。如果您只有两个流和两个设备,您的主内核启动代码可能很简单:

    for(int i=0; i<2; i++) {
        cudaSetDevice(i);
        kernel1<<< grid, block >>>(tex, size);
    }
    

    实际上根本不需要创建任何流。

    【讨论】:

    • 感谢您的快速回复。我仍然遇到同样的问题。当我通过在每个设备上将 i 作为 device_ID 传递来运行我的 cuda 函数 runTest(i) (它包含许多内核)时,程序正在运行......但是一个接一个地运行一个设备......它需要两倍的时间作为单卡。我对流没有太多想法,我只是按照 SDK 示例创建了 2 个不同的流来处理我的两个 GPU 设备...基本上我需要我的程序在两个设备上同时运行...期待您的建议..跨度>
    • runTest() 例程中使用了哪些 API 函数?
    • @vishva 在启动内核后(或在算法中的任何点?),你是在做 cudaThreadSynchronize() 还是 cuCtxSynchronize()。这将序列化您的程序(即一个接一个的设备)。
    • 对不起..我仍然有相同的串行执行并且需要双倍的时间......@talonmies,正如你所建议的,我只是避免了流并在每个例程开始时使用了 cudaSetDevice(dev_ID) ! !!!没有什么变化。实际上,我将 cuda_runtime_api 与 CUDA4.2 一起使用。 runTest(i) 正在调用一些超过两年的内核 ..这里使用 tex1Dfetch(texC,x)..这里 texture texC 作为全局变量..我想知道..我有一个全局变量集,预计两个设备将同时使用..对吗?
    • @Pavan,我没有在内核启动之间使用 cudaDeviceSynchronize。但是很少有内核已经在 __syncthreads() 中使用了。你认为这会导致序列化两个设备吗?实际上我正在运行单个 GPU 开源代码并尝试在 2 Gpus 中运行..
    猜你喜欢
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-17
    • 1970-01-01
    相关资源
    最近更新 更多