简体   繁体   English

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

[英]How to ensure that std::thread are created in multi core?

I am using visual studio 2012. I have a module, where, I have to read a huge set of files from the hard disk after traversing their corresponding paths through an xml. 我正在使用visual studio 2012.我有一个模块,在通过xml遍历相应的路径后,我必须从硬盘中读取一大堆文件。 For this i am doing 为此我正在做

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

In a while loop I am pushing back a new thread into this vector, something like 在while循环中,我将一个新线程推回到这个向量中,就像这样

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

My C++11 multi threading knowledge is limited.The question that I have here , is , how do create a thread on a specific core ? 我的C ++ 11多线程知识是有限的。我在这里的问题是,如何在特定核心上创建一个线程? I know of parallel_for and parallel_for_each in vs2012, that make optimum use of the cores. 我知道vs2012中的parallel_for和parallel_for_each,可以充分利用内核。 But, is there a way to do this using standard C++11? 但是,有没有办法使用标准C ++ 11?

As pointed out in other comments, you cannot create a thread "on a specific core", as C++ has no knowledge of such architectural details. 正如其他注释中所指出的,您无法在“特定核心”上创建线程,因为C ++不了解此类架构细节。 Moreover, in the majority of cases, the operating system will be able to manage the distribution of threads among cores/processors well enough. 此外,在大多数情况下,操作系统将能够足够好地管理核心/处理器之间的线程分布。

That said, there exist cases in which forcing a specific distribution of threads among cores can be beneficial for performance. 也就是说,存在这样的情况,其中在核之间强制特定的线程分布对于性能是有益的。 As an example, by forcing a thread to execute onto a one specific core it might be possible to minimise data movement between different processor caches (which can be critical for performance in certain memory-bound scenarios). 作为示例,通过强制线程执行到一个特定核心上,可以最小化不同处理器高速缓存之间的数据移动(这对于某些存储器绑定场景中的性能可能是关键的)。

If you want to go down this road, you will have to look into platform-specific routines. 如果你想走这条路,你将不得不研究特定于平台的例程。 Eg, for GNU/linux with POSIX threads you will want pthread_setaffinity_np() , in FreeBSD cpuset_setaffinity() , in Windows SetThreadAffinityMask() , etc. 例如,对于你将要POSIX线程的GNU / Linux pthread_setaffinity_np()在FreeBSD的cpuset_setaffinity()在Windows SetThreadAffinityMask()等。

I have some relevant code snippets here if you are interested: 如果您有兴趣,我在这里有一些相关的代码片段:

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

I'm fairly certain that core affinity isn't included in std::thread. 我很确定核心亲和力不包含在std :: thread中。 The assumption is that the OS is perfectly capable of making best possible use of the cores available. 假设操作系统完全能够最好地使用可用的内核。 In all but the most extreme of cases you're not to going to beat the OS's decision, so the assumption is a fair one. 除了最极端的情况之外,你不会打败操作系统的决定,所以假设是公平的。

If you do go down that route then you have to add some decision making to your code to take account of machine architecture to ensure that your decision is better than the OSes on every machine you run on. 如果您确实沿着这条路走下去,那么您必须在代码中添加一些决策,以考虑机器架构,以确保您的决策优于您运行的每台机器上的操作系统。 That takes a lot of effort! 这需要付出很多努力! For starters you'll be wanting to limit the number of threads to match the number of cores on the computer. 对于初学者,您将希望限制线程数以匹配计算机上的核心数。 And you don't have any knowledge of what else is going on in the machine; 而且你不知道机器上还有什么; the OS does! 操作系统呢!

Which is why thread pools exist. 这就是线程池存在的原因。 They tend by default to have as many threads as there are cores, automatically set up by the language runtime. 默认情况下,它们通常具有与核心一样多的线程,由语言运行时自动设置。 AFAIK C++11 doesn't have one of those. AFAIK C ++ 11没有其中之一。 So the one good thing you can do to get the optimum performance is to find out how many cores there are and limit the number of threads you have to that number. 因此,为了获得最佳性能,您可以做的一件好事就是找出有多少核心并限制您拥有的线程数。 Otherwise it's probably just best to trust the OS. 否则,最好是相信操作系统。

Joachim Pileborg's comment is well worth paying attention to, unless the work done by each thread outweighs the I/O overhead. Joachim Pileborg的评论非常值得关注,除非每个线程完成的工作超过了I / O开销。

As a quick overview of threading in the context of dispatching threads to cores: 作为将线程分派到核心的上下文中的线程快速概述:

Most modern OS's make use of kernel level threads, or hybrid. 大多数现代操作系统都使用内核级线程或混合线程。 With kernel level threading, the OS "sees" all the threads in each process; 使用内核级线程,操作系统“看到”每个进程中的所有线程; in contrast to user level threads, which are employed in Java, where the OS sees a single process, and has no knowledge of threading. 与Java中使用的用户级线程相反,操作系统看到单个进程,并且不了解线程。 Now, because, with kernel level threading, the OS can recognise the separate threads of a process, and manages their dispatch onto a given core, there is the potential for true parallelism - where multiple threads of the same process are run on different cores. 现在,因为使用内核级线程,操作系统可以识别进程的单独线程,并管理它们在给定内核上的调度,因此可能存在真正的并行性 - 同一进程的多个线程在不同的内核上运行。 You, as the programmer, will have no control over this however, when employing std::thread ; 作为程序员,当使用std::thread时,你将无法控制它; the OS decides. 操作系统决定。 With user level threading, all the management of threads are done at the user level, with Java, a library manages the "dispatch". 使用用户级线程,线程的所有管理都在用户级完成,使用Java,库管理“调度”。 In the case of hybrid threading, kernel threading is used, where each kernel thread is actually a set of user level threads. 在混合线程的情况下,使用内核线程,其中每个内核线程实际上是一组用户级线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM