Вот два куска кода из ядра 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» в более медленную память, когда скобка закрывается. Это вероятное объяснение? Что я могу сделать?
Заранее спасибо!
ОБНОВЛЕНИЕ: Это также выполняется менее чем за одну секунду: (но с раскомментированием любой строки, оно возвращается к крайне медленной). Это без внесения каких-либо других изменений в циклы, а значение1 по-прежнему объявляется в том же месте, что и раньше.
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 - чрезвычайно хитрое искусство! Я до сих пор не совсем понимаю, что происходит, но, по крайней мере, теперь я знаю, как это исправить!