c++ - 奇怪的 OpenCL 调用 C++ 的副作用以提高循环性能

标签 c++ opencl intel

我正在使用 OpenCL 开发一个 C++ 项目。我将 CPU 用作带有 intel OpenCL runtime 的 OpenCL 设备

我注意到在调用 OpenCL 函数时有一个奇怪的副作用。这是一个简单的测试:

#include <iostream>
#include <cstdio>
#include <vector>
#include <CL/cl.hpp>

int main(int argc, char* argv[])
{
  /*
      cl_int status;
  std::vector<cl::Platform> platforms;
  cl::Platform::get(&platforms);
  std::vector<cl::Device> devices;
  platforms[1].getDevices(CL_DEVICE_TYPE_CPU, &devices);
  cl::Context context(devices);
  cl::CommandQueue queue = cl::CommandQueue(context, devices[0]);
  status = queue.finish();
  printf("Status: %d\n", status);
*/

  int ch;
  int b = 0;
  int sum = 0;
  FILE* f1;
  f1 = fopen(argv[1], "r");

  while((ch = fgetc(f1)) != EOF)
  {
    sum += ch;
    b++;
    if(b % 1000000 == 0)
      printf("Char %d read\n", b);
  }
  printf("Sum: %d\n", sum);

}

这是一个简单的循环,逐个字符地读取文件并将它们相加,这样编译器就不会尝试优化它。

我的系统是运行 Ubuntu 14.10 的 Core i7-4770K、2TB HDD 16GB DDR3。上面的程序以一个 100MB 的文件作为输入,大约需要 770 毫秒。这与我的硬盘速度一致。到目前为止一切顺利。

如果您现在反转注释并仅运行 OpenCL 调用区域,则大约需要 200 毫秒。同样,到目前为止,一切都很好。

Buf如果全部取消注释,程序耗时超过2000ms。我期望 770ms + 200ms,但它是 2000ms。您甚至可以注意到 for 循环中输出消息之间的延迟增加。这两个区域(OpenCL 调用和读取字符)应该是独立的。

我不明白为什么使用 OpenCL 会干扰简单的 C++ for 循环性能。这不是简单的 OpenCL 初始化延迟。

我正在编译这个例子:

g++ weird.cpp -O2 -lOpenCL -o weird

我也尝试过使用 Clang++,但结果是一样的。

最佳答案

这很有趣。这是因为 getc 在队列被实例化时成为线程安全版本,因此时间增加是锁的抓取释放周期 - 我不确定为什么/如何发生这种情况,但这是 AMD OpenCL 的决定性点带有英特尔 CPU 的 SDK。我很惊讶我和 OP 的时间基本相同。

https://software.intel.com/en-us/forums/topic/337984

您可以尝试通过将 getc 更改为 getc_unlocked 来解决此特定问题。

对我来说,它使它回到了 930 毫秒 - 超过 750 毫秒的时间增加主要花在了平台和上下文创建线上。

关于c++ - 奇怪的 OpenCL 调用 C++ 的副作用以提高循环性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29967782/

相关文章:

sdk - 从哪里获得 OpenCL SDK?

database - Berkeley DB Intel - ARM 可移植性

multithreading - `xchg` 是否包含 `mfence` 假设没有非时间指令?

c++ - 通过哈夫曼表重建哈夫曼树

c++ - VC++ : Invalid template argument

cuda - BLAS 等效于 GPU 的 LAPACK 函数

c++ - OpenCL 或 CUDA 走哪条路?

c++ - 计算间隔中数字频率的有效算法

c++ - 访问属于 WiFi 监听器回调成员函数的类的成员

caching - clflush 指令是否仅从 1 级缓存刷新 block ?