为什么我没有得到与此代码的I / O计算重叠?

时间:2017-10-26 22:45:25

标签: asynchronous cuda cuda-streams

以下计划:

#include <iostream>
#include <array>

using clock_value_t = long long;

__device__ void gpu_sleep(clock_value_t sleep_cycles)
{
    clock_value_t start = clock64();
    clock_value_t cycles_elapsed;
    do { cycles_elapsed = clock64() - start; }
    while (cycles_elapsed < sleep_cycles);
}

__global__ void dummy(clock_value_t duration_in_cycles)
{
    gpu_sleep(duration_in_cycles);
}

int main()
{
    const clock_value_t duration_in_clocks = 1e7;
    const size_t buffer_size = 5e7;
    constexpr const auto num_streams = 2;

    std::array<char*, num_streams> host_ptrs;
    std::array<char*, num_streams> device_ptrs;
    std::array<cudaStream_t, num_streams> streams;
    for (auto i=0; i<num_streams; i++) {
        cudaMallocHost(&host_ptrs[i], buffer_size);
        cudaMalloc(&device_ptrs[i], buffer_size);
        cudaStreamCreateWithFlags(&streams[i], cudaStreamNonBlocking);
    }
    cudaDeviceSynchronize();
    for (auto i=0; i<num_streams; i++) {
        cudaMemcpyAsync(device_ptrs[i], host_ptrs[i], buffer_size, 
            cudaMemcpyDefault, streams[i]);
        dummy<<<128, 128, 0, streams[i]>>>(duration_in_clocks);
        cudaMemcpyAsync(host_ptrs[i], device_ptrs[i], buffer_size, 
            cudaMemcpyDefault, streams[i]);
    }
    for (auto i=0; i<num_streams; i++) { cudaStreamSynchronize(streams[i]); }
    for (auto i=0; i<num_streams; i++) {
        cudaFreeHost(host_ptrs[i]);
        cudaFree(device_ptrs[i]);
    }
}

应导致I / O重叠并计算第一个和第二个流上的工作:当第一个流的主机到设备结束时,第一个流的内核可以启动,但是可以进行第二个流的主机到设备传输。相反,我得到以下时间轴,没有重叠:

enter image description here

认为我已经覆盖了我的基础以确保重叠。流是非阻塞的(实际上,在第一个HtoD之前,工作的排队结束);主机内存是固定的...所以我看不到有什么重叠?

在GNU / Linux Mint 18.2上使用CUDA 8.0.61和NVIDIA GTX 650 Ti Boost。但是驱动程序是v384.59。

1 个答案:

答案 0 :(得分:-2)

好吧,它一定是我的GPU型号的东西,因为使用Fedora 25和GTX Titan X,我得到:

enter image description here