我对处理器,内核,线程和并行性的理解是否正确?

On *_*PIP 1 c# parallel-processing multithreading asynchronous task

我一直试图深入了解这些概念是如何相关的.让我举一个简单的例子,解释一下思考,以便你能够纠正它.

假设我想尝试对两个数组进行排序

int[] A = { ... }; // very large, very unsorted 
int[] B = { ... }; // very large, very unsorted 
Run Code Online (Sandbox Code Playgroud)

通过对它们进行排序"与我的系统并行,我可以对它们进行排序".我充分利用了这样一个事实,即Parallel.ForEach做了很多东西,我只是写

var arrays = new List<int[]>(A, B);
Paralell.ForEach(arrays, (arr) => { Array.Sort(arr); });
Run Code Online (Sandbox Code Playgroud)

现在让我说我在具有以下规范的机器上编译并运行它:

  1. 1个处理器,1个核心
  2. 1个处理器,多个核心
  3. 2个处理器,每个处理器至少有一个核心

在情况1中,绝对不可能获得性能增益.它对A进行排序,然后对B进行排序,就像在常规foreach循环中一样.

在案例2中,也没有性能提升,因为除非你有多个处理器,否则你的机器不能"一次做多于一件事. "即使最终在不同的线程中对它们进行排序,控制线程的CPU也会A的一点排序,B的一点点排序,A的一点点等等,这不仅仅比排序所有的A然后全部的B更有效.

由于前一种情况中提到的原因,案例3是唯一可能获得性能提升的案例.

有人会批评我的理解吗?这是对还是错?(我没有计算机科学专业.所以请在曲线上给我评分.)

Han*_*ant 5

在案例1 ...它排序A,然后排序B

这不是线程的工作原理.操作系统快速上下文切换两个线程.在Windows上,默认情况下每秒发生64/3次.交错使得它看起来像A和B同时被排序.不容易观察到,调试器必须让你看看Array.Sort(),它不会.当然,速度不是很快,但放缓速度相当小.它是廉价的上下文切换,不需要重新加载页面映射表,因为线程属于同一个进程.您只需支付可能已删除的缓存,每3/64秒添加约5微秒(慢0.1%)很难准确测量.

在案例2中,...然后你的机器不能"一次做多于一件事"

它可以,每个核心可以同时执行Sort().主要是多核处​​理器.但它们必须共享一个资源,即内存总线.重要的是阵列的大小和RAM芯片的速度.大型阵列不适合处理器高速缓存,从技术上讲,存储器总线可能会被来自处理器内核的请求所饱和.在这种情况下没有帮助的是元素类型,比较两个int非常快,因为它只需要一条CPU指令.期望是x2加速,但如果你观察它需要更长时间,那么你就知道RAM是瓶颈.

案例3是唯一可能获得性能提升的案例

不见得.多处理器机器通常具有NUMA架构,为每个处理器提供自己的内存总线.它们之间的互连可用于将数据从一个总线转移到另一个总线.但是这样的处理器有多个核心.操作系统的工作就是弄清楚如何有效地使用它们.由于线程属于同一个进程,因此共享数据,它将强烈支持在同一处理器的内核上调度线程,并避免在互连上施加负载.所以期望它的表现与案例2相同.

这些是粗略的指导方针,您实际测量的现代机器设计要求.