Оптимизация ядра JNCI/JCOL
У меня есть ядро, работающее в открытом CL (через интерфейс jocl), которое работает ужасно медленно по сравнению с другими ядрами, я пытаюсь понять, почему и как его ускорить. Это ядро очень простое. единственная задача - определить количество точек выборки, которые у нас есть. Он копирует каждую N-ю точку из входного массива в меньший выходной массив, чтобы уменьшить наш размер массива.
Ядру передается число с плавающей точкой, указывающее, сколько точек пропустить между "хорошими" точками. Таким образом, если он набрал 1,5, он пропустит одно очко, десять два, затем один и т. Д., Чтобы в среднем пропустить каждые 1,5 балла. Массив ввода уже находится в графическом процессоре (он был сгенерирован более ранним ядром), а выходной массив останется в ядре, поэтому нет затрат на передачу данных в ЦПУ или из него.
Это ядро работает в 3-5 раз медленнее, чем любое другое ядро; и в 20 раз медленнее некоторых быстрых ядер. Я понимаю, что на меня наложен штраф за то, что я не объединяю свои массивы доступа; но я не могу поверить, что это заставит меня бежать так ужасно медленно. После того, как все остальные ядра касаются каждого семпла в массиве, я думаю, что прикосновение к любому семплу X в массиве, даже если оно не объединено, должно быть примерно с той же скоростью, по крайней мере, касание каждого семпла в массиве.
Исходное ядро фактически уничтожило два массива одновременно для реальных и мнимых данных. Я попытался разделить ядро на два вызова ядра: один для уничтожения реальных и один для уничтожения мнимых данных; но это не помогло вообще. Также я попытался "развернуть" ядро, чтобы один поток отвечал за прореживание 3-4 точек; но это не помогло никому. Я попытался возиться с размером данных, передаваемых в каждый вызов ядра (то есть один вызов ядра для многих тысяч точек данных или несколько вызовов ядра для меньшего числа точек данных), что позволило мне настроить небольшой прирост производительности; но не на порядок, мне нужно, чтобы это ядро считалось достойным реализации на GPU.
просто чтобы дать представление о масштабе, ядру требуется 98 мс для выполнения за одну итерацию, в то время как FFT требует всего 32 мс для того же размера входного массива, а каждое другое ядро занимает 5 или менее мс. Что еще может заставить такое простое ядро работать так абсурдно медленно по сравнению с остальными ядрами? Возможно ли, что я на самом деле не могу оптимизировать это ядро в достаточной степени, чтобы гарантировать запуск его на GPU. Мне не нужно, чтобы это ядро работало быстрее, чем процессор; просто не так медленно по сравнению с процессором, поэтому я могу сохранить всю обработку на графическом процессоре.
1 ответ
Оказывается, проблема не в ядре вообще. Вместо этого проблема в том, что когда я пытаюсь освободить буфер, который я уничтожил, он останавливает всю программу, пока ядро (и все остальные ядра в очереди) завершают работу. Похоже, что это работает неправильно, крелаза должна только уменьшать счетчик, насколько я понимаю, а не блокировать очередь. Тем не мение; важно то, что мое ядро работает эффективно, как и должно быть.