我知道这个问题被问过好几次,但在我的应用程序中,关键是要把握好时间,所以我可能想再试一次:
我像这样计算内核方法的时间,首先使用 clock_t 计算 CPU 时钟时间;
clock_t start = clock(); // Or std::chrono::system_clock::now() for WALL CLOCK TIME
openCLFunction();
clock_t end = clock; // Or std::chrono::system_clock::now() for WALL CLOCK TIME
double time_elapsed = start-end;
还有我的 openCLFunction():
{
//some OpenCLKernelfunction
clFlush(queue);
clFinish(queue);
}
两种方法的结果有很大的不同,老实说我不知道哪个是正确的,因为它们是以毫秒为单位的。我可以相信 CPU 时钟时间吗?有没有一种不关心结果的确定的测量方法?(请注意,我调用了两个函数来完成我的内核函数。)
最佳答案
有(至少)3 种方法来为 OpenCL/CUDA 执行计时:
- 使用 CPU 计时器 + 队列刷新
- 使用 OpenCL/CUDA 事件
- 使用外部分析器工具(例如 AMD 提供的任何工具或用于 nVIDIA 卡的 nvprof)
您的第一个示例属于第一类,但是 - 您似乎没有刷新 OpenCL 函数使用的队列(我假设这是一个将内核排入队列的函数)。所以 - 除非以某种方式强制执行同步,否则您要测量的是将内核排入队列并在此之前或之后执行您所做的任何 CPU 端工作所花费的时间。这可以解释与 clFlush/clFinish 方法的差异。
造成差异的另一个原因可能是设置/拆卸工作(例如内存分配或运行时内部开销),您的第二种方法需要时间,而您的第一种方法不需要。
最后要注意的是,由于测量不准确或使用它们所需的开销不同,这三种方法都会产生略有不同的结果。但是,如果您的内核很小,这些差异可能不会那么小:根据我的经验,分析器提供的内核执行时间与事件测量时间,在 CUDA 和 nVIDIA Maxwell 和 Pascal 卡上可能相差数十微秒。这一事实的教训是:
- 尝试在相关且可能的情况下衡量更多数据,并根据数据量进行标准化。
- 在进行比较时,在衡量执行时间的方式上保持一致。
关于c++ - 测量 OpenCL 应用程序的运行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50955943/