0

我有几个关于多线程的问题,我是 c++11 多线程的新手。

  1. 我想将我的算法的一些块移动到不同的线程,但是,一旦进入块,操作应该按顺序执行。例如,一个线程标记字符串,另一个线程将这些标记转换为双精度/浮点数。实现这一目标的最佳方法是什么。我知道 std::lock 但是,它是有代价的。原子呢?

  2. 如果我在单独的核心中创建线程会更优化吗?VS2012 具有使用内核的 parallel_for/parallel_for_each。

  3. 何时使用 parallel_for/parallel_for_each 和 std::thread 需要考虑哪些标准?

4

2 回答 2

0

对于您的第一点,您正在寻找的是一个多线程锁定队列,您可以将其用作线程之间的缓冲区和通信介质。有了这个,您可以形成一条处理流水线,就像在现实生活中的工厂中一样,每个线程从一个队列中获取要处理的元素并将结果放到另一个队列中。

在这种情况下,最简单的尝试是创建一个使用某种队列的类,std::deque例如,该类被 a 保护免受并发访问std::mutex,并使用 astd::condition_variable或其他此类机制来通知队列中何时有可用数据(为消费者)。

然后用这些新块实现你的算法并对其进行基准测试,看看它是否真的更快,因为使用现代处理器和缓存,使算法成为单线程并并行运行几次可能会更容易。

于 2013-06-29T03:35:47.610 回答
0

大多数时候,您根本不想将单独的线程用于简单的序列,例如对字符串进行标记,然后将标记转换为双精度。

相反,当您在线程之间拆分任务时,您希望找到不需要按顺序完成的事情。恰恰相反,您通常希望尽可能减少线程之间的交互。

因此,不是让一个线程标记化,另一个转换为双精度,您通常更喜欢将标记化和转换一起进行双精度,但将输入分成几个大数据块,每个如果哪个会由单个线程处理。

即便如此,最终也可能没有什么(如果有的话)真正的好处。我首先在一个线程中编写代码,然后进行一些分析。鉴于标记化和转换数据所涉及的处理量很小,单个线程很有可能能够以足够快的速度进行处理以使用所有可用的内存带宽。在这种情况下,除非您使用的系统可能(例如)在完全独立的处理器上运行多个线程,否则使用更多线程不太可能有真正的好处,因此您的可用内存带宽可以扩展(至少在某种程度上)以及您使用的核心。

多个线程将(至少可能,并且通常实际上也是)在多个内核上运行。parallel_for/parallel_for_each旨在简化某些特殊情况的并行处理,因此您可以获得多线程的效果,而无需跳过几乎一样多的火焰箍以确保正确的行为。

std::thread当您希望线程进行异构处理时,确定使用而不是 parallel_for (或类似)的明显标准是。parallel_for 基本上只接受循环的迭代并并行执行它们。如果您的处理(大部分)没有发生在这样的单个循环中,std::thread则可能会产生更好的结果。

于 2013-06-29T04:34:53.043 回答