【问题标题】:CUDA: Memory copy to GPU 1 is slower in multi-GPUCUDA:多 GPU 中到 GPU 1 的内存复制速度较慢
【发布时间】:2011-02-03 08:44:42
【问题描述】:

我公司设置了两台 GTX 295,所以一台服务器总共有 4 个 GPU,我们有几台服务器。 与 GPU 0、2 和 3 相比,我们的 GPU 1 特别慢,所以我写了一个小速度测试来帮助找出问题的原因。

//#include <stdio.h>
//#include <stdlib.h>
//#include <cuda_runtime.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cutil.h>

__global__ void test_kernel(float *d_data) {
    int tid = blockDim.x*blockIdx.x + threadIdx.x;
    for (int i=0;i<10000;++i) {
        d_data[tid] = float(i*2.2);
        d_data[tid] += 3.3;
    }
}

int main(int argc, char* argv[])
{

    int deviceCount;                                                         
    cudaGetDeviceCount(&deviceCount);
    int device = 0; //SELECT GPU HERE
    cudaSetDevice(device);


    cudaEvent_t start, stop;
    unsigned int num_vals = 200000000;
    float *h_data = new float[num_vals];
    for (int i=0;i<num_vals;++i) {
        h_data[i] = float(i);
    }

    float *d_data = NULL;
    float malloc_timer;
    cudaEventCreate(&start);
    cudaEventCreate(&stop); cudaEventRecord( start, 0 );
    cudaMemcpy(d_data, h_data, sizeof(float)*num_vals,cudaMemcpyHostToDevice);
    cudaMalloc((void**)&d_data, sizeof(float)*num_vals);
    cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &malloc_timer, start, stop );
    cudaEventDestroy( start );
    cudaEventDestroy( stop );


    float mem_timer;
    cudaEventCreate(&start);
    cudaEventCreate(&stop); cudaEventRecord( start, 0 );
    cudaMemcpy(d_data, h_data, sizeof(float)*num_vals,cudaMemcpyHostToDevice);
    cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &mem_timer, start, stop );
    cudaEventDestroy( start );
    cudaEventDestroy( stop );

    float kernel_timer;
    cudaEventCreate(&start);
    cudaEventCreate(&stop); cudaEventRecord( start, 0 );
    test_kernel<<<1000,256>>>(d_data);
    cudaEventRecord( stop, 0 ); cudaEventSynchronize( stop ); cudaEventElapsedTime( &kernel_timer, start, stop );
    cudaEventDestroy( start );
    cudaEventDestroy( stop );

    printf("cudaMalloc took %f ms\n",malloc_timer);
    printf("Copy to the GPU took %f ms\n",mem_timer);
    printf("Test Kernel took %f ms\n",kernel_timer);

    cudaMemcpy(h_data,d_data, sizeof(float)*num_vals,cudaMemcpyDeviceToHost);

    delete[] h_data;
    return 0;
}

结果是

GPU0 cudaMalloc 耗时 0.908640 毫秒 复制到 GPU 耗时 296.058777 毫秒 测试内核耗时 326.721283 毫秒

GPU1 cudaMalloc 耗时 0.913568 毫秒 复制到 GPU 耗时 663.182251 毫秒 测试内核耗时 326.710785 毫秒

GPU2 cudaMalloc 耗时 0.925600 毫秒 复制到 GPU 耗时 296.915039 毫秒 测试内核耗时 327.127930 毫秒

GPU3 cudaMalloc 耗时 0.920416 毫秒 复制到 GPU 耗时 296.968384 毫秒 测试内核耗时 327.038696 毫秒

如您所见,GPU 的 cudaMemcpy 是 GPU1 时间量的两倍。这在我们所有的服务器之间都是一致的,总是 GPU1 很慢。 任何想法为什么会这样? 所有服务器都运行 Windows XP。

【问题讨论】:

  • 您是否使用 GPU 卡来显示视频以及运行 CUDA 内核?
  • 是的,很可能是 GPU1。但是记忆副本的时间要加倍?
  • 当我在一台 GPU 机器上运行相同的代码时,其中单个 GPU 用于显示和 CUDA 执行,它仍然快 300 毫秒左右,所以显示无法解释额外的 300 毫秒运行时间
  • 尝试更改用于显示的 GPU 并重新运行测试。不是确定性测试,但相当不错。
  • 您将卡插入的插槽的规格是什么? GPU1 是否可以在电气 x8 插槽中,而其余的在 x16 插槽中?

标签: performance memory cuda multi-gpu


【解决方案1】:

这可能是您的 pci 总线的问题,请尝试将卡更换到不同的插槽中,看看问题是否仍然存在。如果这是一个问题,请通过更快的插槽将所有数据复制到 gtx295 上,然后使用 sli top 将其复制到另一个(慢 pci 总线)gpu。

【讨论】:

    【解决方案2】:

    如果您可以使用更快的显卡的 gddr 来加载,那么您可以在更高的带宽下进行设备设备传输,这也可能有助于解决此问题。此外,请使用 NVidia 的带宽测试检查您的带宽,以获得一些物理结果并进行测试。

    祝你好运!

    【讨论】:

      【解决方案3】:

      您是否在双处理器设置中运行?当前 Tylersburg 芯片组中存在一个错误,即路径 x86 (0) 到 GPU (1) 的带宽比从 x86 (0) 到 GPU (0) 的直接路径慢。英特尔应该发布一个新版本来修复这个错误。尝试使用任务集将您的测试进程锁定到特定的 CPU,看看会得到什么结果。

      问候 标记

      【讨论】:

        【解决方案4】:

        这是驱动程序问题。更新到最新的驱动修复了它

        【讨论】:

          猜你喜欢
          • 2019-04-18
          • 2013-06-06
          • 2019-12-07
          • 2012-06-15
          • 2012-10-31
          • 1970-01-01
          • 2011-09-14
          • 2018-08-14
          • 2015-11-12
          相关资源
          最近更新 更多