[更新:] 我现在正在生成多个进程并且它工作得相当好,尽管基本的线程问题仍然存在。[/]
我正在尝试编写一个编译一堆 opencl 内核的 c++ (g++ 4.6.1) 程序。大部分时间都花在 clBuildProgram 中。(这是基因编程,实际上运行代码和评估适应性要快得多。)我正在尝试线程化这些内核的编译,但到目前为止没有任何运气。此时,线程之间没有共享数据(除了具有相同的平台和设备引用),但它一次只能运行一个线程。我可以将此代码作为多个进程运行(只是在 linux 的不同终端窗口中启动它们),然后它将用完多个内核,但不在一个进程中。我可以使用具有相同基本线程代码(std::thread)的多个内核,只需要基本数学,所以我认为它' 与 opencl 编译或我忘记的一些静态数据有关。:) 有任何想法吗?我已经尽力使这个线程安全,所以我很难过。
我正在使用 AMD 的 SDK(opencl 1.1,大约 2010 年 6 月 13 日)和 5830 或 5850 来运行它。SDK 和 g++ 不是最新的。上次我为了获得更新的 g++ 安装了更新的 linux 发行版时,我的代码以一半的速度运行(至少 opencl 编译是),所以我回去了。(刚刚检查了该安装上的代码,它以一半的速度运行,仍然没有线程差异。)另外,当我说它一次只运行一个线程时,它会启动所有线程,然后在两个线程之间交替,直到它们完成,然后做接下来的两个,等等。看起来所有线程都在运行,直到代码开始构建程序。我没有在 clBuildProgram 中使用回调函数。我意识到这里有很多可能出错的地方,没有代码很难说。:)
我很确定这个问题发生在 clBuildProgram 内部或调用中。我正在打印这里花费的时间,被推迟的线程将在第一次编译时返回很长的编译时间。这些 clBuildProgram 调用之间唯一共享的数据是设备 ID,因为每个线程的 cl_device_id 具有相同的值。
这就是我启动线程的方式:
for (a = 0; a < num_threads; a++) {
threads[a] = std::thread(std::ref(programs[a]));
threads[a].detach();
sleep(1); // giving the opencl init f()s time to complete
}
这是它陷入困境的地方(这些都是被传递的局部变量,尽管设备 ID 将是相同的):
clBuildProgram(program, 1, & device, options, NULL, NULL);
每个线程是否具有唯一的上下文或命令队列似乎没有区别。我真的怀疑这是我提到它的原因。:)
更新:使用 fork() 生成子进程将适用于此。