我是多线程编程的新手。我一直在阅读一些文章,但有两个要点我不完全确定。
- 如果我有一个单线程代码(顺序),并且我在多核处理器上运行它。操作系统是否会尝试将线程划分为多个线程(同时处理依赖项)以利用多核处理器?
- 如果我有一个多线程代码,并且我在单核处理器上运行它。操作系统是否会在不同线程之间进行分时(与多个进程相同的方式)?
1) 否
例如,如果应用使用英特尔数学库并使用正确的开关进行编译,则 FFT 等例程将在运行时拆分为与机器内核数匹配的单独线程。您的源代码仍然是"单线程",但库正在您背后创建和销毁线程。
类似地,一些编译器(例如英特尔的icc,Sun的C编译器)可能会将一些循环转换为单独的线程,每个线程处理迭代的份额。同样,源代码看起来是单线程的,但编译器代表您生成线程代码。这有点像自动将一些 OpenMP 应用于源代码。
操作系统无法再次猜测应用程序将要做什么,因此它们无法像这样进行干预。库和编译器知道将要发生什么,所以他们可以。
已经开发了这样的库和编译器技巧,以便程序员可以轻松地从"单"线程代码中提取更高的性能。英特尔开始将此类功能添加到他们的数学库中,大约在他们开始转向多核CPU的同时。这个想法是(从程序员的角度来看)创造更好的"单"线程性能的印象,而速度实际上是由多个内核提供的。Sun开始做多处理器计算机时也是如此。
随着每个人或多或少放弃对单核性能进行重大改进,这是唯一的出路。
2)是的。不然怎么做?
-
否,操作系统没有足够的信息来执行此操作。在并行化中,您需要考虑操作之间的依赖关系。一些编译器尝试这样做,他们有更多关于代码意图的信息。但即使他们往往也无法有效地做到这一点。
-
是的,例如 Linux 调度程序甚至不区分线程和进程。