关于多线程:如何在多个内核上编译OpenCL程序?

How to compile OpenCL-programs on multiple cores?

OpenCL程序/内核在运行时使用clBuildProgram()函数进行构建/编译。我的程序动态创建要构建的内核,因此要花费大量时间来编译它们。当然,看到有很多内核并且它们彼此完全独立,我希望将此工作划分为多个内核,如下面的代码片段所示:

这个人似乎有一个非常相似的问题,但这是6年前的,解决方案还不能令人满意imo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
ThreadPool tempPool = ThreadPool();
auto start = std::chrono::steady_clock::now();

for (int reps = 0; reps < 50; reps++) {
    tempPool.addJob([this] () {
        auto start = std::chrono::steady_clock::now();

        //These would hold the program sources
        std::vector<const char*> sources = {sourceCode.toRawUTF8()};
        std::vector<const size_t> sourceLengths = {sourceCode.getNumBytesAsUTF8()};

        cl_int ret;
        cl_program program = clCreateProgramWithSource(getCLContext()(), 1, sources.data(), sourceLengths.data(), &ret);

        // Build the program
        ret = clBuildProgram(program, 1, &getCLDevices()[0](), NULL, NULL, NULL);
        if (ret) {
            //Generic error checking
        }

        auto singleDuration = std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - start).count();
    });
}

//Simple way to wait for all jobs to be finished
while (tempPool.getNumJobs() > 0) {
    Thread::sleep(1);
}

 auto totaDuration = std::chrono::duration <double, std::milli> (std::chrono::steady_clock::now() - start).count();

我使用此ThreadPool设置所做的所有事情都会使速度提高5-6(我有8个线程),这是可以预期的。但是,构建OpenCL内核则没有。似乎同一时间只能建立一个内核。

有解决方案吗?我在MacOS atm上,但是我也会对Linux / Windows感兴趣。

如果没有,是否可以构建不涉及clBuildProgram()但涉及gcc或类似解决方案的OpenCL内核?


(令您感到惊讶的是,您平台的驱动程序还没有多线程。您确定您的调用确实是并行的。)

如果您仍然陷于困境,那么接下来可能会遇到麻烦的骇客,该骇客的骇客可以扩展您所引用问题中的解决方案。对于某些驱动程序,clCreateProgramWithBinaries要快得多。因此,

  • 派生新进程(或调用使用相同设备集的帮助程序可执行文件)
  • 每个子进程先调用clCreateProgramWithSource,然后调用clBuildProgram
  • 子代调用clGetProgramInfo(...CL_PROGRAM_BINARIES...)来获取二进制文件,然后通过文件,管道或其他进程间通信将其传递回。
  • 同样,我会先检查一下您的设置代码,然后再一起窃听此hack。