сколько времени нужно, чтобы позвонить в opencl? - PullRequest
3 голосов
/ 05 августа 2011

В настоящее время я реализую алгоритм, который выделяет линейную алгебру на маленьких матрицах и векторах.код быстрый, но мне интересно, имеет ли смысл реализовывать его на gpgpu вместо процессора.

Я могу хранить большинство матриц и векторов в памяти графического процессора в качестве шага предварительной обработки и иметь профили алгоритмов умножения, алгоритмы, конечно, намного быстрее в графическом процессоре.

но теперь для моего реального вопроса, как я могу определить накладные расходы на вызовы на процессор от процессора?сколько циклов я теряю, чтобы мой код выполнялся и все такое прочее?

Надеюсь, у кого-нибудь есть входные данные?

Ответы [ 4 ]

6 голосов
/ 05 августа 2011

Трудно определить точные «издержки» вызова OpenCL, потому что операции на GPU могут выполняться параллельно с тем, что еще выполняется на CPU. В зависимости от вашего приложения вы можете, например, выполнить передачу фрагмента данных в графический процессор из вашего приложения и, в частности, выполнить некоторую предварительную обработку в ЦП следующего фрагмента данных. Точно так же, пока код выполняется на графическом процессоре, вы можете выполнять некоторые подготовительные работы с процессором над некоторыми данными, необходимыми в будущем.

Передачи в GPU будут осуществляться через передачи DMA, которые в целом очень быстрые. Исходя из моего опыта, я смог передать около 4 МБ данных порядка 4 миллисекунд в графический процессор (современный графический процессор, современная материнская плата), выполняя некоторую обработку данных, которые были отправлены ранее. Исходя из этого, можно с уверенностью сказать, что вы можете загружать и загружать порядка 1 ГБ данных в секунду в графический процессор и выполнять некоторую обработку этих данных.

В вашем случае узким местом будет либо GPU, либо сторона процессора. Сторона процессора, если она не может передавать, скажем, 1 ГБ подготовленных данных в графический процессор в секунду. Это может быть очень ограничено вашим дисковым вводом / выводом.

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

Не измеряйте только часть обработки GPU, потому что передачи и обработка на GPU будут конкурировать за время контроллера памяти GPU и будут влиять на скорость друг друга.

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

2 голосов
/ 05 августа 2011

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

Кроме того, если вы очень серьезно относитесь к точности своей алгебры, тогда вы можете подумать, что операции, которые вы хотитевыполнение может быть недоступно изначально на GPU с двойной точностью.

Учитывая, что вы говорите, что ваши матрицы и векторы малы, я предлагаю проверить SIMD-оптимизацию, которая может улучшить производительность вашего алгоритма на CPU.

1 голос
/ 13 декабря 2012

Вы можете использовать объекты clEvent для отслеживания времени, которое занимают фактические вычисления (задержка).Если вы на самом деле имеете в виду циклы ЦП, используйте RDTSC (или его встроенную __rdtsc в MSVC), чтобы выполнить синхронизацию с точностью до наносекунды для реальных вызовов API.Инструкция RDTSC (считывание счетчика меток времени) возвращает количество тактов, которые процессор выполнил с момента включения.

Если загрузка действительно проста, вы можете группировать вызовы и, возможно, добавить измерение в свойNDRange для выполнения нескольких вычислений за один вызов.Конечно, детали зависят от реализации вашего ядра.

0 голосов
/ 05 августа 2011

Я предлагаю использовать следующее для измерения количества циклов процессора:

#include <stdlib.h>
#include <time.h>

// ...

clock_t start,end;
start = clock();

// do stuff...

end = clock();

cout<<"CPU cycles used: "<<end-start;
...