В моем ядре необходимо сделать большое количество случайных обращений к небольшой таблице поиска (всего 8 32-битных целых чисел). Каждое ядро имеет уникальную таблицу поиска. Ниже приведена упрощенная версия ядра, иллюстрирующая использование таблицы поиска.
__kernel void some_kernel(
__global uint* global_table,
__global uint* X,
__global uint* Y) {
size_t gsi = get_global_size(0);
size_t gid = get_global_id(0);
__private uint LUT[8]; // 8 words of of global_table is copied to LUT
// Y is assigned a value from the lookup table based on the current value of X
for (size_t i = 0; i < n; i++) {
Y[i*gsi+gid] = LUT[X[i*gsi+gid]];
}
}
Из-за небольшого размера я получаю лучшую производительность, сохраняя таблицу в пространстве памяти __private. Однако из-за случайного характера обращения к таблице поиска производительность по-прежнему сильно снижается. Если код таблицы поиска удален (например, заменен простой арифметической операцией), хотя ядро и выдаст неверный ответ, производительность возрастет более чем в 3 раза.
Есть ли способ лучше? Я упустил из виду какую-то функцию OpenCL, обеспечивающую эффективный произвольный доступ к очень маленьким участкам памяти? Может ли быть эффективное решение с использованием векторных типов?
[править] Обратите внимание, что максимальное значение X равно 7, но максимальное значение Y равно 2^32-1. Другими словами, используются все биты таблицы поиска, поэтому ее нельзя упаковать в меньшее представление.
__constant
памяти для своих справочных таблиц? Графические процессоры часто реализуют отдельные кэши и пути доступа к памяти для постоянной памяти, чтобы ускорить такие вещи, как общие справочные таблицы. - person user57368   schedule 21.10.2011