Если это серийный код:
int i, j;
for(j=0; j<ny; j++)
{
for(i=0; i<nx; i++)
{
x[i + j*nx] *= y[i];
}
}
, то вы должны делать это:
__global__ void fn(float *x, int nx)
{
int tid = blockIdx.x * blockDim.x + threadIdx.x;
int j = tid/nx, i = tid - j * nx;
x[tid] *= y[i];
}
fn<<<nx*ny/B, B>>>(x, nx); // with B = 256, 512, etc.
То, что вы делаете, довольно странно: вы инструктируете каждый потокядра CUDA для итерации по всем значениям tid от 0 до nx * ny и вычислению той же функции, что и версия вашего процессора!Более того, вместо того, чтобы просто перебирать индексы, вы фактически делаете цикл менее эффективнее, чем для версии CPU;другими словами, вы делаете то же самое в каждом потоке, но менее эффективно, чем в 1 потоке на процессоре.Неудивительно, что это медленнее;это должно быть намного, намного медленнее.Ваше ядро CUDA:
int **tid** = blockIdx.x * blockDim.x + threadIdx.x;
int i,j;
for(**tid** = 0; **tid** <nx*ny; **tid**++)
{
j = tid/nx;
i = tid - j*nx;
x[tid] *= y[i];
}
Это делает nx * ny итераций, так же, как ваш код хоста, для каждого потока;вы теряете все преимущества параллелизма, поскольку каждый поток делает одно и то же;вы получите ту же производительность при использовании одного потока в графическом процессоре и тот же результат!
Если это дословный код из вашего исходного файла CUDA, вам нужно изменить его и повторить сравнение;если это код, который вы написали, чтобы помочь объяснить, что ваш код делает для непрофессиональной аудитории, не относящейся к CUDA, то вам нужно представить свой фактический код CUDA, чтобы мы могли видеть, что происходит ... как есть, анализ производительностиЯ сделал - тривиальный - это все, что вы можете ожидать.