У меня возникло странное поведение, когда я запускаю 2 экземпляра ядра для одновременного запуска при совместном использовании ресурсов графического процессора.Одновременное выполнение двух процессов, совместно использующих Tesla K20
Я разработал ядро CUDA, которое предназначено для работы в одном SM (многопроцессор), где потоки выполняют операцию несколько раз (с циклом).
Ядро готово создать только блок, поэтому использовать только один SM.
simple.cu
#include <cuda_runtime.h>
#include <stdlib.h>
#include <stdio.h>
#include <helper_cuda.h>
using namespace std;
__global__ void increment(float *in, float *out)
{
int it=0, i = blockIdx.x * blockDim.x + threadIdx.x;
float a=0.8525852f;
for(it=0; it<99999999; it++)
out[i] += (in[i]+a)*a-(in[i]+a);
}
int main(int argc, char* argv[])
{
int i;
int nBlocks = 1;
int threadsPerBlock = 1024;
float *A, *d_A, *d_B, *B;
size_t size=1024*13;
A = (float *) malloc(size * sizeof(float));
B = (float *) malloc(size * sizeof(float));
for(i=0;i<size;i++){
A[i]=0.74;
B[i]=0.36;
}
cudaMalloc((void **) &d_A, size * sizeof(float));
cudaMalloc((void **) &d_B, size * sizeof(float));
cudaMemcpy(d_A, A, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_B, B, size, cudaMemcpyHostToDevice);
increment<<<nBlocks,threadsPerBlock>>>(d_A, d_B);
cudaDeviceSynchronize();
cudaMemcpy(B, d_B, size, cudaMemcpyDeviceToHost);
free(A);
free(B);
cudaFree(d_A);
cudaFree(d_B);
cudaDeviceReset();
return (0);
}
Так что, если я исполню ядро:
time ./simple
я
real 0m36.659s user 0m4.033s sys 0m1.124s
В противном случае, если я выполнить два экземпляра:
time ./simple & time ./simple
я для каждого процесса:
real 1m12.417s user 0m29.494s sys 0m42.721s
real 1m12.440s user 0m36.387s sys 0m8.820s
Насколько мне известно, расстрелы должны работать одновременно длительностью один (около 36 секунд). Однако они продолжаются в два раза больше базового времени. Мы знаем, что GPU имеет 13 SM, каждый должен выполнить один блок, поэтому ядра создают только 1 блок.
Выполняются ли они в том же SM?
Не должны ли они работать одновременно в разных SM?
EDITED
Для того, чтобы сделать мне яснее я приложу профили одновременного выполнения, полученного от nvprof:
Теперь я хотел бы показать вам поведение одного и того же сценария, но одновременно выполнять два экземпляры matrixMul образца:
Как вы можете видеть, в первом сценарии, ядро ждет другой, чтобы закончить. Хотя во втором сценарии (matrixMul) ядра из обоих контекстов запускаются одновременно.
спасибо.
Я вижу, я не знал об этом, однако, когда я запускаю 2 параллельных экземпляра matrixMul из SDK, они запускаются одновременно. Я предполагаю, что увеличение времени выполнения связано с совместным использованием SM, но представленное ядро настолько мало, что его можно запустить без совместного использования SM. Мы профилировали выполнение, и мы обнаружили, что наше ядро блокирует выполнение другого ядра, в то время как ядро matrixMul не блокирует другие исполнения. Ты знаешь почему? – siserte
Matrixmul не будет запускать ядра одновременно либо из двух отдельных процессов. Вы что-то неправильно истолковываете. Приложения могут запускаться одновременно, но отдельные ядра не будут возникать из отдельных процессов. Профилировщик может проявлять какое-то перекрытие, но это будет представлять активность API. Сами ядра не будут запускаться одновременно. –
Благодарим за ответ, но мы запускаем 2 экземпляра matrixMul, где выполняются 2 ядра в каждом из них. Профили обоих исполнений показывают, что в то же время одновременно работают 2 ядра. Насколько я знаю, CUDA может одновременно обрабатывать несколько ядер. – siserte