使用vc ++ 11进行多线程处理

时间:2013-06-29 03:04:24

标签: multithreading visual-studio-2012 c++11 thread-safety

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

  1. 我想将我的算法的一些块移动到另一个线程,但是,一旦在块内,操作应该按顺序执行。例如,一个线程标记化字符串和其他线程将这些标记转换为double / float。 实现这一目标的最佳方式是什么。我知道std :: lock但是,它需要付出代价。原子怎么样?

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

  3. 使用parallel_for / parallel_for_each和std :: thread时需要考虑的标准是什么?

2 个答案:

答案 0 :(得分:0)

首先,您要查找的是一个多线程锁定队列,您可以将其用作线程之间的缓冲区和通信介质。通过这种方式,您可以形成一个处理流水线,就像在现实生活工厂中一样,每个线程从一个队列处理元素并将结果放到另一个队列中。

在这种情况下尝试最简单的方法是创建一个使用某种队列的类,例如std::deque,以防止std::mutex的并发访问,并使用{ {1}}或其他此类机制,用于通知队列中的数据何时可用(对于消费者而言)。

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

答案 1 :(得分:0)

大多数情况下,你根本不想为一个简单的序列使用单独的线程,比如标记字符串,然后将标记转换为double。

恰恰相反,当你跨越线程分割任务时,你想要找到需要按顺序完成的事情。恰恰相反,你通常希望最小化交互在你的线程之间尽可能多。

因此,不是让一个线程标记化,而是另一个转换为double,你通常更喜欢将标记化和转换加倍,但是将输入分成几个大块的数据,每个如果哪个将由单个线程处理。

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

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

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