2015-07-09 7 views
2

позволяет сказать, что у меня есть три глобальных массива, которые были скопированы в gpu с использованием cudaMemcpy, но этот массив gloabl в c НЕ был выделен с помощью cudaHostAlloc, чтобы выделить память, которая заблокирована на странице, а не просто злоумышленное распределение.Параллельное выполнение ядер в cuda

int a[100],b [100],c[100]; 
cudaMemcpy(d_a,a,100*sizeof(int),cudaMemcpyHostToDevice); 
cudaMemcpy(d_b,b,100*sizeof(int),cudaMemcpyHostToDevice); 
cudaMemcpy(d_c,c,100*sizeof(int),cudaMemcpyHostToDevice); 

теперь у меня есть 10 ядер, которые запускаются в раздельных потоков таким образом, чтобы работать одновременно, и некоторые из них используют глобальный массив скопированный в GPU. , и теперь эти ядра работают для 1000 итераций. им не нужно копировать что-либо обратно на хост во время итераций.

Но проблема в том, что они не выполняются параллельно, а не для серийной моды.

cudaStream_t stream[3]; 

    for(int i=0;i<3;i++)cudaStreamCreate (&stream[i]); 

    for(int i=0;i<100;i++){ 
     kernel1<<<blocks,threads,0,stream[0]>>>(d_a,d_b); 
     kernel2<<<blocks,threads,0,strea[1]>>(d_b,d_c); 
     kernal3<<<blocks,threads,0,stream[2]>>>(d_c,d_a); 
    cudaDeviceSynchronize(); 
    } 

Не понимаю, почему?

ответ

4

Ядра выпустил так:

for(int i=0;i<100;i++){ 
    kernel1<<<blocks,threads>>>(d_a,d_b); 
    kernel2<<<blocks,threads>>>(d_b,d_c); 
    kernal3<<<blocks,threads>>>(d_c,d_a); 
    cudaDeviceSynchronize(); 
    } 

всегда будет работать последовательно. Чтобы заставить ядра запускаться одновременно, они должны быть выпущены до separate CUDA streams. И есть и другие требования. Прочтите documentation.

Вам нужно создать несколько потоков CUDA, а затем запустить свои ядра, как это:

cudaStream_t stream1, stream2, stream3; 
    cudaStreamCreate(&stream1); cudaStreamCreate(&stream2); cudaStreamCreate(&stream3); 

    for(int i=0;i<100;i++){ 
    kernel1<<<blocks,threads,0,stream1>>>(d_a,d_b); 
    kernel2<<<blocks,threads,0,stream2>>>(d_b,d_c); 
    kernal3<<<blocks,threads,0,stream3>>>(d_c,d_a); 
    cudaDeviceSynchronize(); 
    } 

На самом деле наблюдает одновременное выполнение ядра также обычно требует ядер, которые ограничивают использование ресурсов. Если заданное ядро ​​«заполнит» машину, из-за большого количества блоков или потоков на блок, или использования общей памяти или какого-либо другого использования ресурсов, вы фактически не увидите параллелизм; в машине нет места.

Вы также можете просмотреть некоторые коды образцов CUDA, такие как simpleStreams и concurrentKernels.

+0

Извините за опечатки в вопросе, который я произнес, так как вы указали, но он не работал соответственно. I сделали требуемую коррекцию в вопросе – akubs

+2

Код, который вы показали, еще недействителен. У вас есть 'stream [i]' и 'stream1', которые никогда не будут одинаковыми. Во всяком случае, вам, вероятно, необходимо предоставить полный [MCVE] (http://stackoverflow.com/help/mcve). И просмотрите документацию, чтобы узнать все требования к параллельным ядрам. Вы пытались запустить образец concurrentKernels? –

+0

Я согласен с robert, ваши ядра должны использовать ограниченные ресурсы. Если вы используете cuda 7.0, возможно, вы можете использовать новый поток по умолчанию для потоков. http://devblogs.nvidia.com/parallelforall/gpu-pro-tip-cuda-7-streams-simplify-concurrency/ – X3liF

Смежные вопросы