[英]Where is the boundary of start and end of CPU launch and GPU launch of Nvidia Profiling NVPROF?
在CPU和GPU(黃色塊)中內核啟動的開始和結束的定義是什么? 它們之間的界限在哪里?
請注意,CPU和GPU中這些黃色塊的開始,結束和持續時間是不同的。 vecAdd<<<gridSize, blockSize>>>(d_a, d_b, d_c, n);
CPU調用vecAdd<<<gridSize, blockSize>>>(d_a, d_b, d_c, n);
需要那么長時間?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// CUDA kernel. Each thread takes care of one element of c
__global__ void vecAdd(double *a, double *b, double *c, int n)
{
// Get our global thread ID
int id = blockIdx.x*blockDim.x+threadIdx.x;
//printf("id = %d \n", id);
// Make sure we do not go out of bounds
if (id < n)
c[id] = a[id] + b[id];
}
int main( int argc, char* argv[] )
{
// Size of vectors
int n = 1000000;
// Host input vectors
double *h_a;
double *h_b;
//Host output vector
double *h_c;
// Device input vectors
double *d_a;
double *d_b;
//Device output vector
double *d_c;
// Size, in bytes, of each vector
size_t bytes = n*sizeof(double);
// Allocate memory for each vector on host
h_a = (double*)malloc(bytes);
h_b = (double*)malloc(bytes);
h_c = (double*)malloc(bytes);
// Allocate memory for each vector on GPU
cudaMalloc(&d_a, bytes);
cudaMalloc(&d_b, bytes);
cudaMalloc(&d_c, bytes);
int i;
// Initialize vectors on host
for( i = 0; i < n; i++ ) {
h_a[i] = sin(i)*sin(i);
h_b[i] = cos(i)*cos(i);
}
// Copy host vectors to device
cudaMemcpy( d_a, h_a, bytes, cudaMemcpyHostToDevice);
cudaMemcpy( d_b, h_b, bytes, cudaMemcpyHostToDevice);
int blockSize, gridSize;
// Number of threads in each thread block
blockSize = 1024;
// Number of thread blocks in grid
gridSize = (int)ceil((float)n/blockSize);
// Execute the kernel
vecAdd<<<gridSize, blockSize>>>(d_a, d_b, d_c, n);
// Copy array back to host
cudaMemcpy( h_c, d_c, bytes, cudaMemcpyDeviceToHost );
// Sum up vector c and print result divided by n, this should equal 1 within error
double sum = 0;
for(i=0; i<n; i++)
sum += h_c[i];
printf("final result: %f\n", sum/n);
// Release device memory
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
// Release host memory
free(h_a);
free(h_b);
free(h_c);
return 0;
}
CPU黃色塊:
GPU黃色塊:
請注意,您提到的是NVPROF,但是顯示的圖片來自nvvp-可視分析器。 nvprof是命令行分析器
GPU內核啟動是異步的。 這意味着CPU線程啟動內核,但不等待內核完成。 實際上,CPU活動實際上是將內核置於啟動隊列中-如果GPU上發生了其他任何事情,則內核的實際執行可能會延遲。
因此,就時間而言,CPU(API)活動和GPU活動之間沒有定義的關系,除了CPU內核啟動顯然必須(至少稍微)在GPU內核執行之前。
CPU(API)黃色塊表示CPU線程花費在對CUDA運行時庫進行庫調用中以啟動內核(即將其放入啟動隊列中)的時間。 此庫調用活動通常具有與之相關的一些時間開銷,范圍為5-50微秒。 該時間段的開始以到庫中的調用開始為標志。 該階段的結束由庫將控制權返回給您的代碼(即內核啟動后的下一行代碼)的時間標記。
GPU黃色塊表示內核在GPU上執行的實際時間段。 黃色框的開始和結束以GPU上內核活動的開始和結束標記。 這里的持續時間取決於內核中的代碼在做什么以及需要多長時間。
我不認為在任何地方以權威的方式記錄或解釋GPU內核啟動需要大約5-50微秒的CPU時間的確切原因,並且它是一個封閉的源庫,因此您需要承認開銷是某種東西您幾乎無法控制。 如果您設計運行時間很長的內核並完成大量工作,那么這些開銷可能就變得微不足道了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.