Я только начинаю изучать OpenCL. Я пытаюсь получить ощущение какой увеличение производительности ожидать когда движущиеся функции/алгоритмы к GPU.
Наиболее простое ядро, данное в большинстве учебных руководств, является ядром, которое берет два массива чисел и суммирует значение в соответствующих индексах и добавляет их к третьему массиву, как так:
__kernel void
add(__global float *a,
__global float *b,
__global float *answer)
{
int gid = get_global_id(0);
answer[gid] = a[gid] + b[gid];
}
__kernel void
sub(__global float* n,
__global float* answer)
{
int gid = get_global_id(0);
answer[gid] = n[gid] - 2;
}
__kernel void
ranksort(__global const float *a,
__global float *answer)
{
int gid = get_global_id(0);
int gSize = get_global_size(0);
int x = 0;
for(int i = 0; i < gSize; i++){
if(a[gid] > a[i]) x++;
}
answer[x] = a[gid];
}
Я предполагаю, что Вы никогда не могли выравнивать по ширине вычисления этого на GPU, передача памяти взвесит время, это взяло бы вычисления этого на ЦП величинами (я мог бы быть неправ относительно этого, следовательно этот вопрос).
То, что я задаюсь вопросом, - то, что было бы самым тривиальным примером, где Вы будете ожидать значительное ускорение при использовании ядра OpenCL вместо ЦП?
если у вас есть достаточно большой набор матриц, с которыми вы собираетесь выполнять операции линейной алгебры, или если вы, по сути, выполняете одну и ту же операцию с каждым элементом, Я бы расценил это как тривиальный пример. умножение матриц, сложение, fft, свертка и т. д. вы увидите небольшое ускорение без особых усилий. Теперь, если вы хотите увидеть 100-кратное ускорение, вам нужно углубиться в управление памятью и немного узнать о том, что происходит за кулисами.
Для начала я бы порекомендовал начать с pycuda, поскольку начать работу с ней довольно просто, поскольку она обеспечивает очень высокий уровень абстракции и позволяет очень быстро приступить к работе. ознакомьтесь с этим курсом по параллельным вычислениям с использованием cuda от университета Иллинойса http://courses.ece.illinois.edu/ece498/al/ , когда будете готовы погрузиться в дальнейшее изучение.
зависит от определения тривиального. на мой взгляд, это будет матричное произведение матриц, поскольку оно имеет O(3)/O(2)
отношение вычислений к памяти.
Алгоритмы, которые демонстрируют подобное соотношение, вероятно, выиграют от конкуренции на GPU.
После матричного умножения я бы сказал о свертке изображения (например, размытие, денуазинг и т.д.). Посмотрите учебник AMD.
Хотя ваше ядро явно очень тривиально, оно может быть полезным примером, но оно полностью ограничено памятью, поскольку для каждого элемента у вас есть два чтения и одна запись и только одна арифметическая операция. Есть некоторые инструкции для вычисления адреса и т. Д., Но все это практически ничего по сравнению со стоимостью доступа к памяти.
Предполагая, что данные уже находятся в графическом процессоре, вы можете воспользоваться очень высокой пропускной способностью графического процессора для памяти даже для этого простого ядра.
Конечно, графические процессоры полагаются на то, что у вас достаточно потоков, чтобы скрыть задержку памяти, поэтому размер вашей локальной рабочей группы должен быть довольно большим (скажем, 256 или 512), а размер вашей глобальной рабочей группы должен быть очень большим (например, сотни тысяч ), чтобы это было эффективно, но в том-то и дело!
Что такое "самый тривиальный" - это вопрос мнения, но я бы сказал, что вычисление изображения множества Мандельброта - это довольно простое приложение с использованием GPU. Каждая точка полностью независима от всех других точек, поэтому вы можете запустить поток для каждой точки и получить огромное ускорение. Сама формула, которая итерируется, представляет собой простую квадратичную функцию. Я использовал ее в качестве примера в учебнике, который можно найти в моем блоге здесь, просто вычисляя числа, даже не делая изображения, чтобы еще больше упростить задачу. Почти любая неловко параллельная (см. статью в Википедии) проблема является хорошей для начала.