如何衡量OpenCL读数时间?

时间:2014-06-09 12:28:06

标签: java performance profiling opencl

我想确保以clEnqueueReadBuffer()正确的方式确保如何确保将数据从GPU复制到主内存所需的时间。我有点怀疑clFinish()确实做出了贡献。

我通过此

运行10000个浮点数的100x点积并测量时间
  // RUN TIME BLOCK
  println( " Running OpenCL program ... " );
  t1 = System.nanoTime(); 
  for (int reps = 0; reps < 100; reps++) {
    clEnqueueNDRangeKernel(commandQueue, kernel, 1, null, global_work_size, local_work_size, 0, null, null);    
  }
  clFinish(commandQueue); // VERSION 1
  t2 = System.nanoTime(); 
  println( " OpenCL Run Time : "+ ((t2-t1)*1e-9)+" [s] " );

  // READ OUT TIME BLOCK
  t1 = System.nanoTime(); 
  //clFinish(commandQueue); // VERSION 2
  clEnqueueReadBuffer(commandQueue, memObjects[2], CL_TRUE, 0, n * Sizeof.cl_float, dst, 0, null, null);
  t2 = System.nanoTime(); 
  println( " Read-out Time: "+ ((t2-t1)*1e-9)+" [s] " );

得到了结果

 OpenCL Run Time : 2.5124469 [s] 
 Read-out Time: 0.002145424 [s] 

对我而言似乎有点太好2毫秒和<0.1%的总时间...... CPU-GPU通信瓶颈的问题似乎并不那么糟糕。

当我将clFinish(commandQueue);置于Read-out Time块内时,我得到了这些结果

OpenCL Run Time : 1.0892084 [s] 
Read-out Time: 1.4300439 [s] 

另一方面,这似乎太糟糕了......在GPU上进行100次乘法比通过PCI-express复制更快? ......好吧也许


仅限于完整性:

我使用openclp5processing使用jocl和Java jdk 1.7在Ubuntu 12.04 64位上使用Quadro FX 580 GPU和

我的内核很简单(没有优化或任何东西)

  String programSource =     
   "__kernel void sampleKernel(                                                 "+
   "__global const float *a, __global const float *b, __global float *c) {      "+
   "  int gid = get_global_id(0);                                               "+
   "  c[gid] = a[gid] * b[gid];                                                 "+
   "}";

1 个答案:

答案 0 :(得分:1)

测量将数据读回主机的时间的第一种方法是正确的。第二种方法包括一些计算时间。

您正在阅读的数据量为1000000 * sizeof(float) = 4MB。如果这需要2毫秒,那么这意味着您将获得4MB/0.002s = 2 GB/s的带宽。为什么你认为这太好了不可能?您的卡支持PCIe x16,其理论峰值带宽为8 GB / s(单向)。