Работать только с подмножеством буфера в ядре OpenCL - PullRequest
0 голосов
/ 22 марта 2019

Новичок в OpenCL здесь.Я пытаюсь преобразовать численный метод, который я написал в OpenCL для ускорения.Я использую пакет PyOpenCL , как я уже писал один раз на Python, и, насколько я могу судить, нет веской причины использовать версию C.Но я все слышу, если я ошибаюсь в этом.

Мне удалось перевести большую часть функциональности, которая мне нужна, в ядра OpenCL.Мой вопрос о том, как (правильно) сказать OpenCL игнорировать мои граничные / призрачные ячейки.Причина, по которой мне нужно это сделать, заключается в том, что мой метод (например) для точки i обращается к ячейкам на [i-2:i+2], поэтому, если i=1, я убегу с конца массива.Итак - я добавляю несколько дополнительных точек, которые служат для предотвращения этого, а затем просто говорю моему алгоритму работать только на точках [2:nPts-2].Легко понять, как это сделать с помощью цикла for, но я немного более неясен относительно правильного способа сделать это для ядра.

Достаточно ли, например, сделать это(псевдокод)

__kernel void myMethod(...) {
    gid = get_global_id(0);

    if (gid < nGhostCells || gid > nPts-nGhostCells) {
        retVal[gid] = 0;
    }

    // Otherwise perform my calculations
}

или есть другой / более подходящий способ применения этого ограничения?

1 Ответ

0 голосов
/ 22 марта 2019

Это выглядит достаточно.

Ветвление одинаково для nPts-nGhostCells * 2 количества точек, и оно предсказуемо, если nPts и nGhostCells являются константами времени компиляции. Даже если это непредсказуемо, достаточно большие nPts против nGhostCells (1024 против 3) не должны быть заметно медленнее, чем версия с нулевым ветвлением, за исключением задержки операции «или». Даже эта задержка "или" должна быть скрыта за задержкой доступа к массиву благодаря параллелизму на уровне потоков.

В этих точках "останова" в основном 16 или 32 потока потеряли бы некоторую производительность и только на несколько тактов из-за пошагового выполнения SIMD-подобных архитектур.

Если вам случается кодировать какое-то хаотичное ветвление, например, путь кода, управляемого данными, то вы должны разбить их на разные ядра (для разных регионов) или отсортировать их перед ядром, чтобы среднее ветвление между соседними потоками было минимизировано.

...