2016-12-30 17 views
1

Я хочу, чтобы два API CUBLAS (например, cublasDgemm) выполнялись одновременно в двух cudaStream.Как сделать несколько API CUBLAS (например, cublasDgemm) действительно выполняться одновременно в multi cudaStream

Как мы знаем, CUBLAS API асинхронный, уровень 3 процедуры, как cublasDgemm не блокировать хост, это означает, что следующие коды (по умолчанию cudaStream) будет работать на одновременно:

cublasDgemm(); 
cublasDgemm(); 

НО, когда я просматриваю программу с помощью «NVIDIA Visual Profiler», она показывает, что они работают упорядоченно.

Затем я пытаюсь сделать их привязку к различным cudaStreams, то псевдокод:

// Create a stream for every DGEMM operation 
cudaStream_t *streams = (cudaStream_t *) malloc(batch_count*sizeof(cudaStream_t)); 
for(i=0; i<batch_count; i++) 
    cudaStreamCreate(&streams[i]); 

// Set matrix coefficients 
double alpha = 1.0; 
double beta = 1.0; 

// Launch each DGEMM operation in own CUDA stream 
for(i=0; i<batch_count; i++){ 
    // Set CUDA stream 
    cublasSetStream(handle, streams[i]); 

    // DGEMM: C = alpha*A*B + beta*C 
    cublasDgemm(handle, 
       CUBLAS_OP_N, CUBLAS_OP_N, 
       dim, dim, dim, 
       &alpha, 
       d_A[i], dim, 
       d_B[i], dim, 
       &beta, 
       d_C[i], dim); 
} 

Когда Batch_Count = 5, результат показал на "NVIDIA Визуальный Profiler" является:

Multi-CublasDegmm Rountines Execution Result With Multi-Streams

Результат показывает, что они все еще работают на упорядоченной основе. Как сделать мульти cublas APIs работать на самом деле одновременно в нескольких cudaStreams, как это:

Multi-Kernels Execution Result With Multi-Streams,They Run on Really Concurrnently

ли кто-нибудь имеет какие-либо идеи? Благодарю.

+2

Вызов гемма над определенным размером запустит ядра с достаточным количеством блоков для заполнения графического процессора, чтобы в последующих запусках ядра не было места для запуска одновременно. Ядра, которые достаточно малы (с точки зрения блоков), будут стремиться так быстро, что параллелизм снова трудно засвидетельствовать. В этом вопросе есть предположение, что можно запускать любые 2 ядра одновременно; Это просто неправда. Свидетельство о параллельности ядра на самом деле довольно сложно и требует тщательно продуманных запусков ядра, даже не считая CUBLAS. –

+0

@Robert Crovella, спасибо за ваш комментарий. –

+0

@Robert Crovella, спасибо за ваш комментарий. НО я сомневаюсь, что «вызов gemm над определенным размером запустит ядра с достаточным количеством блоков для заполнения графического процессора, чтобы последующие запуска ядра не имели возможности запускать одновременно». , потому что при попытке выполнить gemm с разным размером матриц (размер достаточно мал <например m = n = k = 16>, это означает, что ресурс gpu имеет место для запуска другой геммы), результат тот же. –

ответ

1

Во-первых, спасибо за комментарии @Robert Crovella.

В соответствии с рекомендацией @Robert Crovella и моим исследованием мы можем запускать несколько API CUBLAS (например, cublasDgemm) одновременно в некоторых особых случаях, но в большинстве случаев это невозможно.

ПРИМЕР 1: Когда я выполнить cublasDgemm с большими тускнеет из (т = п = к = 1024 * 8) на К40, профилировщик показывают результат, как следующее: cublasDgemm with dims of (M=N=K=1024*8)

Случай 2: Когда я выполнить cublasDgemm с малые dims (m = n = k = 64) на K40, профилировщик показывает результат следующим образом: cublasDgemm with dims of (M=N=K=64)

CASE 3: НО когда я выполняю cublasDgemm с dims (m = n = k = 256) на K40 , профилировщик показывает результат следующим образом: cublasDgemm with dims of (M=N=K=256)

Из результатов CASE 1 и CASE 2 это показывает, что мы не можем одновременно использовать не только большие тусклые, но и малые dims, API CUBLAS. Причиной для случая 1 является то, что ресурсы gpu были израсходованы, поэтому не осталось места для запуска других подпрограмм, а для случая 2 это задержка запуска двух ядер, из-за которых трудно увидеть con.

+0

Если вы посмотрите внимательно, вы заметите, что ядра из обоих потоков перекрываются во всех случаях - второе ядро ​​всегда запускается до завершения первого ядра. – tera

+0

@tera Спасибо. Да, вы правы. Можете ли вы объяснить какое-то объяснение этому явлению. –

+1

Это показывает, что выполняется параллельное выполнение - второе ядро ​​запускается после того, как ресурсы освобождаются первым, с небольшой задержкой. Просто вы не получаете * полного * перекрытия по причинам, указанным в вашем ответе. Вы можете сравнить эти результаты профилировщика с тем случаем, когда вы запускаете оба Dgemms в том же потоке, чтобы найти небольшое перекрытие, полностью уйти. – tera

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

  • Нет связанных вопросов^_^