Cuda 用于计算带宽的时间

Cuda 用于计算带宽的时间,cuda,Cuda,我试图找出我的代码在CUDA GEforce 8800 gtx最大86GB/s的情况下使用的有效带宽。但我不确定何时使用。目前我使用的是带指令调用内核与不带指令调用内核之间的区别。这是正确的方法吗?(我使用的公式是->有效bw=(字节读+写)/时间) 此外,我的内核调用开销非常大(接近1秒)。有没有办法消除它?您可以使用cuda事件对内核进行精确计时 //declare the events cudaEvent_t start; cudaEvent_t stop; float kernel_ti

我试图找出我的代码在CUDA GEforce 8800 gtx最大86GB/s的情况下使用的有效带宽。但我不确定何时使用。目前我使用的是带指令调用内核与不带指令调用内核之间的区别。这是正确的方法吗?(我使用的公式是->有效bw=(字节读+写)/时间)


此外,我的内核调用开销非常大(接近1秒)。有没有办法消除它?

您可以使用cuda事件对内核进行精确计时

//declare the events
cudaEvent_t start;
cudaEvent_t stop;
float kernel_time;

//create events before you use them
cudaEventCreate(&start);
cudaEventCreate(&stop);

//put events and kernel launches in the stream/queue
cudaEventRecord(start,0);
myKernel <<< config >>>( );
cudaEventRecord(stop,0);

//wait until the stop event is recorded
cudaEventSynchronize(stop);

//and get the elapsed time
cudaEventElapsedTime(&kernel_time,start,stop);

//cleanup
cudaEventDestroy(start);
cudaEVentDestroy(stop);
//声明事件
cudaEvent\u t启动;
不要停下来;
浮动时间;
//在使用事件之前创建它们
cudaEventCreate(&start);
cudaEventCreate(&stop);
//将事件和内核启动放入流/队列中
cudaEventRecord(开始,0);
myKernel>();
cudaEventRecord(停止,0);
//等待直到停止事件被记录
CUDAEVENTS同步(停止);
//并获取经过的时间
CUDAEVENTERLASEDTIME(&kernel_time,start,stop);
//清理
cudaEventDestroy(启动);
cudaEVentDestroy(停止);

您可以使用cuda事件相当精确地为内核计时

//declare the events
cudaEvent_t start;
cudaEvent_t stop;
float kernel_time;

//create events before you use them
cudaEventCreate(&start);
cudaEventCreate(&stop);

//put events and kernel launches in the stream/queue
cudaEventRecord(start,0);
myKernel <<< config >>>( );
cudaEventRecord(stop,0);

//wait until the stop event is recorded
cudaEventSynchronize(stop);

//and get the elapsed time
cudaEventElapsedTime(&kernel_time,start,stop);

//cleanup
cudaEventDestroy(start);
cudaEVentDestroy(stop);
//声明事件
cudaEvent\u t启动;
不要停下来;
浮动时间;
//在使用事件之前创建它们
cudaEventCreate(&start);
cudaEventCreate(&stop);
//将事件和内核启动放入流/队列中
cudaEventRecord(开始,0);
myKernel>();
cudaEventRecord(停止,0);
//等待直到停止事件被记录
CUDAEVENTS同步(停止);
//并获取经过的时间
CUDAEVENTERLASEDTIME(&kernel_time,start,stop);
//清理
cudaEventDestroy(启动);
cudaEVentDestroy(停止);

以GBps为单位的有效带宽=((Br+Bw)/10^9)/时间

Br=内核从DRAM读取的字节数

Bw=内核在DRAM中写入的字节数

时间=内核占用的时间

例如,您测试将2048x2048浮点矩阵(每个4字节)从GPU的DRAM中的一个位置复制到另一个位置的有效带宽。公式如下:

带宽(GB/s)=((2048x2048 x 4 x 2)/10^9)/内核占用的时间

在这里:

2048x2048(矩阵元素)

4(每个元素有4个字节)

2(一个用于读取,一个用于写入)


/10^9将B转换为GB。

以GBps为单位的有效带宽=((Br+Bw)/10^9)/Time

Br=内核从DRAM读取的字节数

Bw=内核在DRAM中写入的字节数

时间=内核占用的时间

例如,您测试将2048x2048浮点矩阵(每个4字节)从GPU的DRAM中的一个位置复制到另一个位置的有效带宽。公式如下:

带宽(GB/s)=((2048x2048 x 4 x 2)/10^9)/内核占用的时间

在这里:

2048x2048(矩阵元素)

4(每个元素有4个字节)

2(一个用于读取,一个用于写入)


/10^9将B转换为GB。

来回发送几个字节不会得到精确的结果。cuda工具包附带一个bandwith test-使用它。@Dave-问题不是确定他的卡的带宽,而是确定“效率”您看到的1s开销是否会在每次启动内核时发生?(即,如果您在一次程序运行中启动多个内核,那么该开销是仅在第一次启动时发生还是在所有启动时发生?)Sry用于延迟响应。是的,所有调用都会有开销。。每次我启动内核时。事实上,即使是空内核也需要一些时间。来回发送几个字节也不会得到精确的结果。cuda工具包附带一个带测试的工具-使用它。@Dave-问题不是确定他的卡的带宽,而是确定他的卡的带宽与最大带宽相比,他的内核的“效率”。您看到的1s开销是否在每次启动内核时都会发生?(即,如果您在单个程序运行中启动多个内核,那么开销是仅在第一次启动时还是在所有启动时?)Sry用于延迟响应。是的,所有调用都有开销。每次我启动内核时。事实上,即使是空内核也需要一些时间。是的,这与我所做的类似。但是内核启动部分需要相当长的时间。对总共6个2000*512的映像进行下采样需要接近1.39秒(仅内核)而不是1.16秒(调用空内核)。我使用cudaTimers来衡量这一点。是的,我不知道如何评价你的启动。你调用你的内核多少次?在启动它之前是否有cudaMalloc或任何其他cuda调用?我只在我的程序中调用内核一次(以减少样本).程序中几乎没有CUDAMALLOC,但在启动和从内核返回之间没有CUDAMALLOC。它类似于starttimer…内核…stoptimer。然后我使用cutGetTimerValue除以1000以秒为单位报告时间。是的,这与我所做的类似。但是内核启动部分需要相当长的时间。对总共6幅2000*51的图像进行下采样2需要接近1.39秒(仅内核)而不是1.16秒(调用空内核)。不过我使用cudaTimers来衡量这一点。是的,我不知道如何评价您的启动。您调用内核多少次?启动前是否有cudaMalloc或任何其他cuda调用?我只在程序中调用内核一次(减少示例)。程序中几乎没有CUDAMALLOC,但在启动和从内核返回之间没有。它类似于starttimer…内核…stoptimer。然后我使用cutGetTimerValue除以1000以秒为单位报告时间。谢谢jawad。我在cuda手册中读到了这一点。但是它没有回答我的问题。如果我计算内核启动之间的时间返回时,我的带宽非常差