Я попытался скомпилировать вашу программу с помощью следующей командной строки, используя инструменты компилятора PGI 13.10:
pgcc -acc -ta=nvidia,cc20,cuda5.0 -o t1 t1.c -Minfo
И получил такой вывод:
scaled:
10, Generating present_or_copy(v1[0:n])
Generating present_or_copyin(v2[0:n])
Generating NVIDIA code
Generating compute capability 2.0 binary
11, Complex loop carried dependence of '*(v2)' prevents parallelization
Loop carried dependence of '*(v1)' prevents parallelization
Loop carried backward dependence of '*(v1)' prevents vectorization
Accelerator scalar kernel generated
14, Sum reduction generated for sum
Хотя это указывает на то, что компиляция прошла "успешно", сообщения "предотвращает распараллеливание" указывают на то, что компилятор не успешно действительно воспользовался преимуществами ускорителя. Когда вы видите сообщение Accelerator scalar kernel generated
, вы часто будете недовольны результатами.
Когда я запускаю программу, скомпилированную выше, я получаю сообщение об ошибке выполнения:
call to cuLaunchKernel returned error 701: Launch out of resources
Это ошибка, исходящая из подсистемы выполнения CUDA. Вы можете увидеть или не увидеть такую ошибку в зависимости от того, на каком ускорителе вы пытаетесь запустить. Мы могли бы вникнуть в то, как решить эту проблему, но это действительно не относится к делу, потому что ваша программа не структурирована должным образом, чтобы воспользоваться преимуществами ускорителя.
Компилятор выдает сообщения «предотвращает распараллеливание», потому что он строго относится к указателям vector1
(или v1
) и vector2
(или v2
). Предполагается, что эти указатели могут накладываться друг на друга, и поэтому в этом случае не могут создать правильную параллельную программу. Поскольку это, вероятно, не является вашим намерением (вы, вероятно, намереваетесь v1
и v2
ссылаться на отдельные пробелы), вы можете «успокоить» компилятор, изменив параметры вашей scaled
функции с помощью ключевого слова C99 restrict
. Это позволяет компилятору выполнять свою работу так, как вы, вероятно, предполагали.
Вот измененный код и результаты:
$ cat t1.c
#include <stdio.h>
#include <stdlib.h>
float scaled(float *restrict v1, float *restrict v2, float a, int n)
{
int i;
float sum = 0.0f;
#pragma acc kernels
for(i=0;i<n;i++)
{
v1[i]+=a*v2[i];
sum+=v1[i];
}
return sum;
}
int main(int argc, char* argv[])
{
int n;
float *vector1;
float *vector2;
if( argc > 1 )
n = atoi( argv[1] );
else
n = 100000;
if( n <= 0 ) n = 100000;
vector1=(float*)malloc(n*sizeof(float));
vector2=(float*)malloc(n*sizeof(float));
scaled(vector1, vector2, 3.3, n);
printf("programming done\n");
return 0;
}
$ pgcc -acc -ta=nvidia,cc20,cuda5.0 -o t1 t1.c -Minfo
scaled:
10, Generating present_or_copy(v1[0:n])
Generating present_or_copyin(v2[0:n])
Generating NVIDIA code
Generating compute capability 2.0 binary
11, Loop is parallelizable
Accelerator kernel generated
11, #pragma acc loop gang, vector(128) /* blockIdx.x threadIdx.x */
14, Sum reduction generated for sum
$ ./t1
programming done
$
Если вы не можете получить такие результаты, возможно, проблема связана с машиной / инструментами, на которых вы пытаетесь запустить.
person
Robert Crovella
schedule
05.02.2014