Почему я не получаю перекрытие вычислений ввода-вывода с этим кодом?

Следующая программа:

#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]);
    }
}

должно привести к перекрытию операций ввода-вывода и вычислений между работой над первым и вторым потоками: когда заканчивается передача от хоста к устройству первого потока, может запускаться ядро ​​первого потока, но также может запускаться передача от хоста к устройству второго потока. Вместо этого я получаю следующую временную шкалу без перекрытий:

введите здесь описание изображения

Думаю, я прикрыл свои базы, чтобы обеспечить совпадение. Потоки не блокируются (и действительно, постановка работы в очередь завершается задолго до того, как это сделает первый HtoD); память хоста закреплена ... так что мне не хватает, чтобы увидеть перекрытие?

Использование CUDA 8.0.61 на GNU/Linux Mint 18.2 с NVIDIA GTX 650 Ti Boost. Но драйвер v384.59.


person einpoklum    schedule 26.10.2017    source источник
comment
куда версия? ГП? платформа/ОС? скомпилировать команду? это: "cuda/api_wrappers.h" действительно нужно?   -  person Robert Crovella    schedule 27.10.2017
comment
@RobertCrovella: см. редактирование и мой ответ.   -  person einpoklum    schedule 27.10.2017
comment
Кроме того, дополнительное включение является ненужным.   -  person einpoklum    schedule 27.10.2017


Ответы (1)


Хорошо, это должно быть что-то с моей моделью графического процессора, потому что с Fedora 25 и GTX Titan X я получаю:

введите здесь описание изображения

person einpoklum    schedule 26.10.2017