Вот два фрагмента кода ядра OpenCL, над которым я работаю; время их выполнения сильно различается.
Код довольно сложный, поэтому я упростил его.
Эта версия выполняется менее чем за одну секунду:
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
double nothing = value1;
}
}
, а эта версия запускается примерно за 38 секунд:
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
Как я уже сказал, код несколько сложнее, чем этот (в циклах происходит много других вещей. ), но переменная "ничего" действительно не перемещается непосредственно перед фигурной скобкой к моменту сразу после нее.
Я новичок в OpenCL и не могу понять, что происходит, не говоря уже о том, как это исправить. Излишне говорить, что медленный вариант - это то, что мне нужно в моей реализации. Я пробовал возиться с адресными пространствами (все переменные здесь в __private).
Я могу только представить, что по какой-то причине графический процессор выталкивает переменную value1 в более медленную память, когда скобка закрывается. Это вероятное объяснение? Что я могу сделать?
Заранее спасибо!
ОБНОВЛЕНИЕ: Это тоже занимает менее одной секунды: (но при раскомментировании любой строки все возвращается к крайней медлительности). Это без внесения каких-либо других изменений в циклы, и value1 по-прежнему объявлен в том же месте, что и раньше.
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
// value1 = value2 + value3;
// value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
ОБНОВЛЕНИЕ 2: Код был фактически вложен в другой цикл, подобный этому, с объявлением value1
, как показано:
double value1=0;
for (int kk=0; kk<someNumber3;kk++)
{
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
}
Перемещение, где объявлено value1
, также возвращает нас к быстрый случай:
for (int kk=0; kk<someNumber3;kk++)
{
double value1=0;
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
}
Кажется, OpenCL - чрезвычайно сложное искусство! Я до сих пор не очень понимаю, что происходит, но по крайней мере теперь я знаю, как это исправить!