如何确保在多核中创建std :: thread?

时间:2013-04-04 03:54:14

标签: c++ multithreading concurrency c++11 visual-studio-2012

我正在使用visual studio 2012.我有一个模块,在通过xml遍历相应路径后,我必须从硬盘中读取大量文件。为此我正在做

std::vector<std::thread> m_ThreadList;

在while循环中,我将一个新线程推回到这个向量中,类似于

m_ThreadList.push_back(std::thread(&MyClass::Readfile, &MyClassObject, filepath,std::ref(polygon)));

我的C ++ 11多线程知识是有限的。我在这里的问题是,如何在特定核心上创建一个线程?我知道vs2012中的parallel_for和parallel_for_each,可以充分利用内核。但是,有没有办法使用标准C ++ 11?

3 个答案:

答案 0 :(得分:4)

正如其他评论中所指出的,您无法在“特定核心”上创建线程,因为C ++不了解此类架构细节。此外,在大多数情况下,操作系统将能够很好地管理核心/处理器之间的线程分布。

即,存在这样的情况,其中在核之间强制特定的线程分布可以有益于性能。例如,通过强制线程执行到一个特定的核心,可以最小化不同处理器高速缓存之间的数据移动(这对于某些受内存限制的场景中的性能至关重要)。

如果你想走这条路,你将不得不研究特定于平台的例程。例如,对于带有POSIX线程的GNU / linux,您需要pthread_setaffinity_np(),在FreeBSD cpuset_setaffinity()中,在Windows SetThreadAffinityMask()中等。

如果您有兴趣,我在这里有一些相关的代码片段:

http://gitorious.org/piranhapp0x/mainline/blobs/master/src/thread_management.cpp

答案 1 :(得分:2)

我很确定核心亲和力不包含在std :: thread中。假设操作系统完全能够最好地使用可用的内核。除了最极端的情况之外,你不会打败操作系统的决定,所以假设是公平的。

如果您确实沿着这条路走下去,那么您必须在代码中添加一些决策,以考虑机器架构,以确保您的决策优于您运行的每台机器上的操作系统。这需要付出很多努力!对于初学者,您将希望限制线程数以匹配计算机上的核心数。而且你不知道机器上还有什么;操作系统呢!

这就是存在线程池的原因。默认情况下,它们通常具有与核心一样多的线程,由语言运行时自动设置。 AFAIK C ++ 11没有其中之一。因此,为了获得最佳性能,您可以做的一件好事就是找出有多少核心并限制您拥有的线程数。否则,最好是相信操作系统。

Joachim Pileborg的评论非常值得关注,除非每个线程完成的工作超过了I / O开销。

答案 2 :(得分:0)

作为将线程分派到核心的上下文中的线程的快速概述:

大多数现代操作系统都使用内核级线程或混合线程。使用内核级线程,操作系统“看到”每个进程中的所有线程;与Java中使用的用户级线程相反,操作系统看到单个进程,并且不了解线程。现在,因为通过内核级线程,操作系统可以识别进程的单独线程,并管理它们在给定内核上的调度,有可能实现真正的并行性 - 同一进程的多个线程在不同的内核上运行。作为程序员,当使用std::thread时,你无法控制它;操作系统决定。使用用户级线程,线程的所有管理都在用户级完成,使用Java,库管理“调度”。在混合线程的情况下,使用内核线程,其中每个内核线程实际上是一组用户级线程。