7

我正在使用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 做到这一点?

4

3 回答 3

5

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

也就是说,在某些情况下,强制在内核之间分配特定的线程可能对性能有益。例如,通过强制一个线程在一个特定的内核上执行,可以最大限度地减少不同处理器缓存之间的数据移动(这对于某些内存绑定场景中的性能至关重要)。

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

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

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

于 2013-04-04T09:30:11.370 回答
2

我相当确定核心亲和力不包含在 std::thread 中。假设是操作系统完全有能力充分利用可用的内核。除了最极端的情况外,您不会违背操作系统的决定,所以这个假设是公平的。

如果您确实走这条路,那么您必须在代码中添加一些决策以考虑机器架构,以确保您的决策比您运行的每台机器上的操作系统更好。这需要很大的努力!对于初学者,您可能希望限制线程数以匹配计算机上的内核数。而且您对机器中发生的其他事情一无所知;操作系统可以!

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

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

于 2013-04-04T04:59:24.850 回答
0

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

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

于 2016-06-16T22:19:53.970 回答