0

我正在开发一个进行音频编码/解码的库。如果可用,编码器应能够使用多个内核(即多线程,使用 boost 库)。我现在拥有的是一个执行所有编码相关操作的类。

我要采取的下一步是使该类线程化。所以我想知道如何做到这一点。

我考虑过编写一个线程类,为 n 个内核创建 n 个线程,然后使用适当的参数调用编码器。但也许这有点矫枉过正,不需要另一个类,所以我将使用“用户界面”来创建线程。

我希望有任何建议。

编辑:我被迫使用多个线程进行预处理,使用 CUDA 创建输入数据的统计信息。因此,如果系统中有多个卡,并行使用它们的唯一方法是创建多个线程。

示例: 4 个文件,4 个不同的计算单元(单独的内存,唯一的设备 ID)。每个文件应在一个计算单元上执行。

我现在拥有的是:

class Encoder {
[...]
public:
    worker(T data, int devId);
[...]
}

所以我认为最好的方法是从 main() 线程调用 worker

boost::thread w1(&Encoder::worker, data0, 0);
boost::thread w2(&Encoder::worker, data1, 1);
boost::thread w3(&Encoder::worker, data2, 2);
boost::thread w4(&Encoder::worker, data3, 3);

而不是实现线程类。

4

4 回答 4

2

如果您的编译器支持,请查看OpenMP 。它可以像添加编译器标志并喷洒几个#pragmas 一样简单。

于 2010-03-15T10:00:28.323 回答
1

我认为这个问题更多的是在设计层面,你能详细说明你有什么课程吗?我也在 CUDA 上工作,通常会创建一个接口(也称为外观模式)来使用特定于架构的 (CUDA) 层。

编辑:阅读更新界面后,我认为您做对了。将 Encoder 逻辑保留在类中,并使用普通的 boost::threads 来执行不同的工作单元。只需注意编码器方法中的线程安全即可。

于 2010-03-15T10:38:44.167 回答
1

您当前的建议仅在Encoder::workeris时有效static。我认为是这样。一个问题是,如果您当前的实现支持一种优雅地中止编码作业的方法。我想您的代码中有一些方法:

while( MoreInputSamples ) {
    // Do more encoding
}

这可以通过检查作业是否收到中​​止信号的一些附加条件来修改。我经常从事视频解码工作,我喜欢这样的解码器类:

class Decoder {
public:
    void DoOneStepOfDecoding( AccessUnit & Input );
}

输出通常会发送到一些环形缓冲区。这样,我可以轻松地将其包装在单线程和多线程场景中。

于 2010-03-15T11:04:09.067 回答
1

前面的代码

  boost::thread w1(&Encoder::worker, data0, 0);

直到工人是静态的才有效。

审核计划中有Boost.Task允许您异步调用任何可调用对象,如下所示

  boost::tasks::async(
    boost::tasks::make_task( &Encoder::worker, data0, 0) ) );

这导致 Encoder::worker 在默认线程池上被调用。该函数返回一个句柄,允许知道任务何时执行。

于 2010-04-19T23:05:20.250 回答