Перекрытие вычислений и передачи на Windows - PullRequest
0 голосов
/ 09 марта 2020

У меня возникают некоторые проблемы при попытке наложения вычислений и передачи на Windows (с использованием VS2015 и CUDA 10.1). Код не перекрывается вообще. Но тот же код на Linux, что и ожидаемое поведение.

Вот взгляды из NVVP:

Windows 10 Скриншот NVVP:

NVVP screenshot on Win10/VS2015

Linux Скриншот NVVP:

NVVP screenshot on Linux

Обратите внимание на следующие моменты:

  • моя память хоста PageLocked
  • я использую два разных потока
  • я использую метод cudaMemcpyAsyn c для передачи между хостом и устройством
  • если я запускаю свой код на Linux, все в порядке
  • Я не вижу ничего в документации, описывающей различное поведение этих двух систем.

Итак, вопрос в следующем:

Я что-то упустил? Существует ли способ достижения перекрытия в этой конфигурации (Windows 10 + 1080Ti)?


Вы можете найти код здесь, чтобы воспроизвести проблему:

#include "cuda_runtime.h"

constexpr int NB_ELEMS = 64*1024*1024;
constexpr int BUF_SIZE = NB_ELEMS * sizeof(float);

constexpr int BLK_SIZE=1024;

using namespace std;

__global__
void dummy_operation(float* ptr1, float* ptr2)
{
    const int idx = threadIdx.x + blockIdx.x * blockDim.x;
    if(idx<NB_ELEMS)
    {
        float value = ptr1[idx];
        for(int i=0; i<100; ++i)
        {
            value += 1.0f;
        }

        ptr2[idx] = value;
    }
}


int main()
{
    float *h_data1 = nullptr, *h_data2 = nullptr,
        *h_data3 = nullptr, *h_data4 = nullptr;
    cudaMallocHost(&h_data1, BUF_SIZE);
    cudaMallocHost(&h_data2, BUF_SIZE);
    cudaMallocHost(&h_data3, BUF_SIZE);
    cudaMallocHost(&h_data4, BUF_SIZE);

    float *d_data1 = nullptr, *d_data2 = nullptr,
        *d_data3 = nullptr, *d_data4 = nullptr;

    cudaMalloc(&d_data1, BUF_SIZE);
    cudaMalloc(&d_data2, BUF_SIZE);
    cudaMalloc(&d_data3, BUF_SIZE);
    cudaMalloc(&d_data4, BUF_SIZE);

    cudaStream_t st1, st2;
    cudaStreamCreate(&st1);
    cudaStreamCreate(&st2);

    const dim3 threads(BLK_SIZE);
    const dim3 blocks(NB_ELEMS / BLK_SIZE + 1);

    for(int i=0; i<10; ++i)
    {
        float* tmp_dev_ptr = (i%2)==0? d_data1 : d_data3;
        float* tmp_host_ptr = (i%2)==0? h_data1 : h_data3;
        cudaStream_t tmp_st = (i%2)==0? st1 : st2;
        cudaMemcpyAsync(tmp_dev_ptr, tmp_host_ptr, BUF_SIZE, cudaMemcpyDeviceToHost, tmp_st);
        dummy_operation<<<blocks, threads, 0, tmp_st>>>(tmp_dev_ptr, d_data2);
        //cudaMempcyAsync(d_data2, h_data2);
    }

    cudaStreamSynchronize(st1);
    cudaStreamSynchronize(st2);

    return 0;
}

1 Ответ

1 голос
/ 09 марта 2020

Как указывает @talonmies, для перекрытия вычислений и передач вам нужна карта Graphi c в режиме Tesla Compute Cluster.

Я проверил это поведение, используя старый Quadro P620.

[Edit] Перекрытие между ядрами и копированием, кажется, работает, так как я применил обновление Windows 10 1909.

Я не уверен, что обновление windows включает драйвер graphi c обновлять или нет. Но это нормально :) 1007 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...