Почему быстрее передавать данные с процессора на графический процессор, а не на графический процессор? - PullRequest
0 голосов
/ 12 мая 2018

Я заметил, что передача данных в последние высокопроизводительные графические процессоры происходит быстрее, чем их сбор обратно в ЦП. Вот результаты использования функции сравнительного анализа, предоставленной мне техподдержкой mathworks, работающей на более старом Nvidia K20 и недавнем Nvidia P100 с PCIE:

Using a Tesla P100-PCIE-12GB GPU.
Achieved peak send speed of 11.042 GB/s
Achieved peak gather speed of 4.20609 GB/s

Using a Tesla K20m GPU.
Achieved peak send speed of 2.5269 GB/s
Achieved peak gather speed of 2.52399 GB/s

Я приложил ниже функцию сравнения для справки. В чем причина асимметрии на P100? Зависит ли эта система или это является нормой на современных высокопроизводительных GPU? Можно ли увеличить скорость сбора?

gpu = gpuDevice();
fprintf('Using a %s GPU.\n', gpu.Name)
sizeOfDouble = 8; % Each double-precision number needs 8 bytes of storage
sizes = power(2, 14:28);

sendTimes = inf(size(sizes));
gatherTimes = inf(size(sizes));
for ii=1:numel(sizes)
    numElements = sizes(ii)/sizeOfDouble;
    hostData = randi([0 9], numElements, 1);
    gpuData = randi([0 9], numElements, 1, 'gpuArray');
    % Time sending to GPU
    sendFcn = @() gpuArray(hostData);
    sendTimes(ii) = gputimeit(sendFcn);
    % Time gathering back from GPU
    gatherFcn = @() gather(gpuData);
    gatherTimes(ii) = gputimeit(gatherFcn);
end
sendBandwidth = (sizes./sendTimes)/1e9;
[maxSendBandwidth,maxSendIdx] = max(sendBandwidth);
fprintf('Achieved peak send speed of %g GB/s\n',maxSendBandwidth)
gatherBandwidth = (sizes./gatherTimes)/1e9;
[maxGatherBandwidth,maxGatherIdx] = max(gatherBandwidth);
fprintf('Achieved peak gather speed of %g GB/s\n',max(gatherBandwidth))

Редактировать: теперь мы знаем, что это не зависит от системы (см. Комментарии). Я все еще хочу знать причину ассиметрии или ее можно изменить.

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

Я не знаком с наборами инструментов Matlab GPU, но подозреваю, что вторая передача (которая возвращает данные из GPU) начинается до того, как закончится первая.

% Time sending to GPU
sendFcn = @() gpuArray(hostData);
sendTimes(ii) = gputimeit(sendFcn);
%
%No synchronization here
%
% Time gathering back from GPU
gatherFcn = @() gather(gpuData);
gatherTimes(ii) = gputimeit(gatherFcn);

Аналогичный вопрос для программы на C был размещен здесь:

копирование с графического процессора на процессор выполняется медленнее, чем копирование процессора на графический процессор

В этом случае нет явной синхронизации после запуска потока в графическом процессоре и получения данных результатов из графического процессора. Поэтому функция, которая возвращает данные, в C cudaMemcpy (), должна ждать, пока графический процессор завершит предыдущий запущенный поток, прежде чем передавать данные, увеличивая тем самым время, измеренное для передачи данных.

С помощью Cuda C API можно заставить процессор ждать, пока графический процессор завершит работу ранее запущенных потоков, с помощью:

cudaDeviceSynchronize ();

И только потом начинайте измерять время для передачи данных обратно.

Может быть, в Matlab есть также какой-то примитив синхронизации.

Также в том же ответе рекомендуется измерять время с помощью (Cuda) Events.

В этом POST по оптимизации передачи данных, также в C извините, события используются для измерения времени передачи данных:

https://devblogs.nvidia.com/how-optimize-data-transfers-cuda-cc/

Время передачи данных одинаково в обоих направлениях.

0 голосов
/ 22 мая 2018

Это CW для всех, кто интересуется публикацией тестов со своей машины. Участникам рекомендуется оставлять свои данные на случай, если в будущем возникнет вопрос относительно их результатов.



Система: Win10, 32 ГБ оперативной памяти DDR4-2400 МГц, i7 6700K. MATLAB: R2018a.

Using a GeForce GTX 660 GPU.
Achieved peak send speed of 7.04747 GB/s
Achieved peak gather speed of 3.11048 GB/s

Warning: The measured time for F may be inaccurate because it is running too fast. Try measuring something that takes
longer. 

Автор: Dev-iL



Система: Win7, 32 ГБ оперативной памяти, i7 4790K. MATLAB: R2018a.

Using a Quadro P6000 GPU.
Achieved peak send speed of 1.43346 GB/s
Achieved peak gather speed of 1.32355 GB/s

Автор: Dev-iL

...