答案 0 :(得分:3)
不,每个核心通常可以从指令集执行大多数常规操作。但是"多个处理元素"对于SIMD操作,只需对不同的数据(不同的字节或字)执行单个操作。
例如,[CIImage imageWithCVImageBuffer]微体系结构的每个核心都能够独立于其他核心运行SIMD指令,而here,ARM Cortex-A53和MMX这样的SIMD指令集是首先介绍了单核CPU。
答案 1 :(得分:3)
每个核心都有自己独立的SIMD执行单元。在一个核心中使用SIMD指令不会在其他核心中花费执行资源。即使在相同的物理芯片上,独立的内核也是独立的,因此它们可以分别进入睡眠状态以节省电力,以及各种其他设计原因使它们保持隔离状态。
我所知道的一个例外:AMD Bulldozer有两个弱整数核心共享一个SIMD / FPU并共享一些缓存。他们称之为"集群",它基本上是超线程(SMT)的替代品。请参阅David Kanter's Bulldozer write-up on RealworldTech。
SIMD和多核是正交的:你可以拥有没有SIMD的多核(可能是一些没有FPU / NEON的ARM芯片),你可以拥有没有多核的SIMD。
后者的很多例子,包括最突出的早期x86芯片,如Pentium-MMX,Pentium III / Pentium 4,有MMX / SSE1 / SSE2但是单核CPU。
程序中至少有三种不同的并行性:
Instruction-level parallelism:它可以重叠同一个执行线程中不同指令所完成的一些工作,保留了一个接一个地运行每个指令的错觉。通过构建流水线CPU核心或超标量(每个时钟多个指令),甚至无序执行来利用它。 (有关详细信息,请参阅my answer on a question about that。)
创建软件时:尽可能避免使用长依赖链,从而将此并行性公开给硬件。 (例如,将sum += a[i++]
替换为sum1+=a[i]; sum2+=a[i+1]; i+=2;
:展开多个累加器)。或者使用数组而不是链表,因为加载的下一个地址是廉价计算的,而不是来自内存的数据的一部分,你必须等待缓存未命中。 但大部分ILP已经存在于"正常"代码没有做任何特殊的事情,你构建更大/更高级的硬件来发现更多,并增加每个时钟的平均指令。
Data parallelism :您需要对图像的每个像素或音频文件中的每个样本执行相同的事务。 (例如,混合2个图像,或混合两个音频流)。 通过在每个CPU内核中构建并行执行单元来利用这一点,这样一条指令就可以并行执行16个单字节添加,从而提高吞吐量,而不会增加通过所需的指令数量每个时钟的CPU核心。 这是SIMD :单指令,多数据。
音频/视频是其中最着名的应用,其中加速大量,因为您可以将大量字节或16位元素放入单个固定宽度向量寄存器中。
通过智能编译器自动矢量化循环或手动来利用SIMD。 SIMD将sum += a[i];
转换为sum[0..3] += a[i+0..3]
(每个向量包含4个元素,如使用int
或float
使用32位向量)。
Thread/task-level parallelism:利用多核CPU,通过手动编写多线程代码,或使用OpenMP或其他自动并行化工具来多线程循环,或使用库函数,可以为大矩阵乘法或其他东西启动多个线程。
或者更简单地说,一次运行多个单独的程序。例如使用make -j8
进行编译,以便同时保留8个编译进程。通过在多台计算机的集群上运行工作负载,甚至分布式计算,也可以利用粗粒度的任务级并行性。
但是,多核CPU使得利用细粒度线程级并行性成为可能/高效,其中任务需要共享大量数据(如大型阵列),或通过共享内存进行低延迟通信。 (例如,使用锁来保护共享数据的不同部分,或无锁编程。)
这三种并行是正交的。
在现代CPU上总结一个非常大的float
数组:
您为每个CPU核心启动一个线程,并将每个核心循环放在共享内存中的一个数据块上。 (线程级并行)。我们说,这给你4倍的加速因子。 (即使这可能因为内存瓶颈而不切实际,但你可以想象一些其他计算密集型任务,它们不需要读取如此多的内存,在28核Xeon或双插槽服务器上运行其中两个筹码......)
每个线程的代码将使用SIMD在每个内核上分别执行4或8次添加。 (SIMD)。这为您提供4或8加速因子。 (或AVX512 16)
您可以使用8个向量累加器来展开,以隐藏浮点加法的延迟。 (ILP)。 Skylake的vaddps
指令具有4个周期的延迟和0.5个周期的吞吐量(即每个时钟2个)。因此,8个累加器几乎不足以隐藏延迟并立即保留8个FP添加指令。
单线程标量sum += a[i++]
的总吞吐量增益是所有这些加速因子的乘积:4 * 8 * 8
= 256x非并行化非标准化吞吐量vectorized,single-accumulator ILP-bottlenecked naive implementation,就像你从gcc -O2
得到一个简单的循环。 clang -O3 -march=native -ffast-math
会给SIMD和一些ILP(因为clang在展开时知道如何使用多个累加器,通常使用4,与gcc不同。)
您需要OpenMP或其他自动并行化来利用多个核心。
相关:Why does mulss take only 3 cycles on Haswell, different from Agner's instruction tables?可以更深入地了解ILP和SIMD的多个累加器,用于FMA循环。
答案 2 :(得分:-1)
是。确实如此。但仅从营销的角度来看。在没有SIMD指令的情况下销售uP或uC会很困难。