Я преподаю OpenCL, пытаясь оптимизировать опорный аудиокодер mpeg4dst. Я добился 3-кратного ускорения с помощью векторных инструкций по процессору, но я решил, что графический процессор, возможно, будет лучше.OpenCL slow - не знаю почему
Я сосредоточен на вычислении векторов автокорреляции в OpenCL в качестве своей первой области улучшения. Код ЦП:
for (int i = 0; i < NrOfChannels; i++) {
for (int shift = 0; shift <= PredOrder[ChannelFilter[i]]; shift++)
vDSP_dotpr(Signal[i] + shift, 1, Signal[i], 1, &out, NrOfChannelBits - shift);
}
NrOfChannels = 6
PredOrder = 129
NrOfChannelBits = 150528.
В моем тестовом файле эта функция занимает приблизительно 188 мс для завершения.
Вот мой метод OpenCL:
kernel void calculateAutocorrelation(size_t offset,
global const float *input,
global float *output,
size_t size) {
size_t index = get_global_id(0);
size_t end = size - index;
float sum = 0.0;
for (size_t i = 0; i < end; i++)
sum += input[i + offset] * input[i + offset + index];
output[index] = sum;
}
Вот как это называется:
Согласно приборам, моя реализация OpenCL, кажется, занимает около 13 мс, при этом около 54ms накладных расходов копирования памяти (gcl_memcpy).
Когда я использую гораздо больший тестовый файл, 1 минута 2-канальной музыки против 1 секунды 6-канального, в то время как измеренная производительность кода OpenCL кажется одинаковой, загрузка процессора падает примерно до 50 %, и вся программа занимает примерно 2 раза дольше.
Я не могу найти причины для этого в Инструментах, и я еще ничего не читал, что говорит о том, что я должен ожидать очень тяжелого перебоя в работе и выходе из OpenCL.
Каковы ваши системные характеристики? GPU? ОПЕРАЦИОННЫЕ СИСТЕМЫ? В общем случае накладные расходы на запуск ядра довольно велики на дискретном графическом процессоре. И наихудшие издержки на запуск, которые вы можете получить, - это дискретный графический процессор в Windows Vista или новее (из-за модели драйвера). Кроме того, кажется, что ваше ядро OpenCL работает с относительно небольшим количеством потоков (128 потоков для GPU действительно низки). В идеале ваша проблема должна иметь разные потоки (ndrange) порядка тысячи. Вдобавок к этому, копирование памяти довольно дорогое по шине PciE. Попытайтесь записать его так, чтобы вместо memcpy за цикл итерации вы копировали весь результат после всех вызовов ядра. – sharpneli
Я на OSX 10.9 на Macbook Pro с графической картой NVidia GT 650M. Я удалил второй gcl_memcpy, а также цикл, и я узнал о cl_ndrange, чтобы попытаться получить больше потоков на GPU. Однако из моих тестов я вижу 10 мс для выполнения ядра и 50 мс в gcl_memcpy (это должна быть передача PCIe в обоих направлениях). Это должно дать мне хорошую скорость, ~ 60 мс против ~ 190 мс. Вместо этого я вижу, что время «исчезает», когда процессор используется всего на 40%, а весь процесс занимает почти в два раза больше времени, чем раньше. – Tim