Оптимизация ядра JNCI/JCOL

У меня есть ядро, работающее в открытом CL (через интерфейс jocl), которое работает ужасно медленно по сравнению с другими ядрами, я пытаюсь понять, почему и как его ускорить. Это ядро ​​очень простое. единственная задача - определить количество точек выборки, которые у нас есть. Он копирует каждую N-ю точку из входного массива в меньший выходной массив, чтобы уменьшить наш размер массива.

Ядру передается число с плавающей точкой, указывающее, сколько точек пропустить между "хорошими" точками. Таким образом, если он набрал 1,5, он пропустит одно очко, десять два, затем один и т. Д., Чтобы в среднем пропустить каждые 1,5 балла. Массив ввода уже находится в графическом процессоре (он был сгенерирован более ранним ядром), а выходной массив останется в ядре, поэтому нет затрат на передачу данных в ЦПУ или из него.

Это ядро ​​работает в 3-5 раз медленнее, чем любое другое ядро; и в 20 раз медленнее некоторых быстрых ядер. Я понимаю, что на меня наложен штраф за то, что я не объединяю свои массивы доступа; но я не могу поверить, что это заставит меня бежать так ужасно медленно. После того, как все остальные ядра касаются каждого семпла в массиве, я думаю, что прикосновение к любому семплу X в массиве, даже если оно не объединено, должно быть примерно с той же скоростью, по крайней мере, касание каждого семпла в массиве.

Исходное ядро ​​фактически уничтожило два массива одновременно для реальных и мнимых данных. Я попытался разделить ядро ​​на два вызова ядра: один для уничтожения реальных и один для уничтожения мнимых данных; но это не помогло вообще. Также я попытался "развернуть" ядро, чтобы один поток отвечал за прореживание 3-4 точек; но это не помогло никому. Я попытался возиться с размером данных, передаваемых в каждый вызов ядра (то есть один вызов ядра для многих тысяч точек данных или несколько вызовов ядра для меньшего числа точек данных), что позволило мне настроить небольшой прирост производительности; но не на порядок, мне нужно, чтобы это ядро ​​считалось достойным реализации на GPU.

просто чтобы дать представление о масштабе, ядру требуется 98 мс для выполнения за одну итерацию, в то время как FFT требует всего 32 мс для того же размера входного массива, а каждое другое ядро ​​занимает 5 или менее мс. Что еще может заставить такое простое ядро ​​работать так абсурдно медленно по сравнению с остальными ядрами? Возможно ли, что я на самом деле не могу оптимизировать это ядро ​​в достаточной степени, чтобы гарантировать запуск его на GPU. Мне не нужно, чтобы это ядро ​​работало быстрее, чем процессор; просто не так медленно по сравнению с процессором, поэтому я могу сохранить всю обработку на графическом процессоре.

1 ответ

Решение

Оказывается, проблема не в ядре вообще. Вместо этого проблема в том, что когда я пытаюсь освободить буфер, который я уничтожил, он останавливает всю программу, пока ядро ​​(и все остальные ядра в очереди) завершают работу. Похоже, что это работает неправильно, крелаза должна только уменьшать счетчик, насколько я понимаю, а не блокировать очередь. Тем не мение; важно то, что мое ядро ​​работает эффективно, как и должно быть.

Другие вопросы по тегам