多核处理器上的线程化,并发性和并行性

我一直在阅读有关这个​​话题,并且对多线程和并行性有点困惑; 我读过这个问题

“线程在多线程系统中如何在CORES中分配?假设我有一个创建6个线程的程序,我的系统有3个CORES,在这种情况下线程将在3个CORE之间分配,或者所有线程都执行相同的核心?” - 具有3个逻辑核心的物理CPU

这个问题的答案表明,我必须告诉操作系统哪个内核执行了什么,这是用Java或C#语言进行多线程处理时的普遍真理吗?

链接到问题

在我没有指定哪个核心在用Java或C#等语言编写的多线程程序中能够实现并行性的场景中?

我一直在学习一些erlang,并且在产生这些过程时已经达到了产卵过程的主题; erlang是否告诉操作系统将不同的进程分配给不同的内核? 我看到这个代码来自你学习一些erlang,这产生了10个进程,每个都会打印出一个数字,但为什么使用timer:sleep? 是不是只是让程序看起来并行,而只是让某些东西停下来,让别的东西可以运行(就像并发)?

4> G = fun(X) -> timer:sleep(10), io:format("~p~n", [X]) end.
#Fun<erl_eval.6.13229925>
5> [spawn(fun() -> G(X) end) || X <- lists:seq(1,10)].

我在java中实现了这一点,并得到了类似的结果,我创建了6个线程,每个“线程”都有一个循环,它打印出线程名称,然后一个数字会休眠10毫秒。

public class ThreadTest {

public static void main(String args[]) {

    Thread t1 = new Thread(new Thread2());
    Thread t2 = new Thread(new Thread3());
    Thread t3 = new Thread(new Thread4());
    Thread t4 = new Thread(new Thread5());
    Thread t5 = new Thread(new Thread6());

    t1.start();        
    t2.start();
    t3.start();
    t4.start();
    t5.start();
  }

}

看看这两个程序是他们同时执行还是并行执行? 我也意识到电脑速度很快,但即使我没有让Java程序进入睡眠状态,它也会一个接一个地打印出这些东西。 然而,对于erlang,如果我删除睡眠,它有时会打印出大量的数字,然后打印进程的数量并继续计数,或者打印出所有数字,然后打印出最后的进程列表。

关于上面的问题,java是在一个核心上同时处理事务(使用上下文切换),还是利用更多内核并行处理,但速度太快,无法给我随机结果? (没有睡觉)

Erlang是否使用了更多的内核并行处理,因为它有时会在计数过程中打印出进程列表? (没有睡觉)

注意:我有意删除了其他线程的代码,只是认为解释类的作用会更好。


传统的操作系统(OS),例如Linux,管理许多进程的执行(进程本质上对应于程序)。

一个进程最初在一个线程上执行,但可以在执行时创建其他线程 。 OS的主要任务之一是管理所有进程线程的执行。

  • 当只有一个处理器时,OS调度程序上下文在不同线程之间切换以提供并发执行
  • 当有多个处理器时,每个处理器本质上运行OS调度器的一个实例,从而执行正在等待运行的线程。 结果是并行执行要执行的一组线程。
  • 并发或线程在一种语言中的行为取决于它是如何实现的。

    使用Java,JVM的实现很可能会使用OS提供的线程机制,即POSIX(请参阅此问题)。 多线程Java程序的性能将由OS决定。 例如,请参阅Linux调度程序的详细信息。

    Erlang的情况稍有不同,我认为这是混乱的根源。 由于Erlang提倡使用大量进程(即线程),并且这些进程与消息传递进行通信,所以线程实现必须高效。 由于这些原因,POSIX线程并不合适,Erlang虚拟机有它自己的线程机制。 它的工作方式是通过为每个核心分配一个具有固定相关性的操作系统线程,并在每个核心上运行Erlang调度程序。


    操作系统如何在多核计算机上调度线程的原理与在单核机器上完成线程的方式并没有太大区别。 实际上,每个内核都运行OS调度器的副本,并且彼此交谈并决定如何最好地将线程分配给内核。 如果其中一个调度程序发现它没有准备好的线程在其核心上运行,它将运行一个在另一个核心中被阻塞的就绪线程。

    问题是这些内核大多是异步的,彼此独立,并且不能保证执行顺序。 因此,不同线程输出字符串的顺序不是确定性的,每次运行程序时都可能很容易发生变化。

    所有这些都是有效的,因为今天的多核计算机实现了对称多处理(SMP)。 所有内核都可以看到所有内存,因此选择哪个内核最适合运行线程并没有真正的问题。

    然而,我们从Xeons等那里得到的SMP是'假',也就是说它们是由QPI合成的SMP的部分NUMA。 AMD处理器完全是NUMA,SMP是通过Hypertransport合成的。 QPI和HyperTransport非常好,但是操作系统不应忽视的开销。 简而言之,一个核心上的线程访问电子连接到不同核心的内存需要更长的时间。 所以一个好的操作系统会尝试在最接近他们正在访问的内存的内核上运行线程,以获得良好的性能。 在Xeon领域,由于机器的默认存储器映射在CPU之间交错(试图使伪造的SMP更好),所以这是复杂的。

    因此,只要您开始深入研究核心关联和将线程绑定到特定内核(操作系统允许您如果真的想要这样做),您的程序必须完全理解硬件的微电子体系结构,才会发现自己正在运行。 总的来说,这并不是完全现实的,在几乎所有情况下,让操作系统为你解决问题可能更好。

    链接地址: http://www.djcxy.com/p/79411.html

    上一篇: threading, concurrency and parallelism on a multicore processor

    下一篇: Most useful and instructive functional