Architecture 比较SIMD机器和MIMD机器上执行的指令数

Architecture 比较SIMD机器和MIMD机器上执行的指令数,architecture,cpu-architecture,Architecture,Cpu Architecture,我们希望尽可能高效地执行下面的循环。我们有两台不同的机器,一台MIMD机器和一台SIMD机器 for (i=0; i<2000; i++) for (j=0; j<3000; j++) X_array[i][j] = Y_array[j][i] + 200; 对于(i=0;i来说,如果不做更多您没有指定的假设,那么几乎没有足够的信息来回答这个问题 使用SIMD将此问题矢量化并非易事,因为X[i][j]的数组索引与Y[j][i]的数组索引相反,因此问题在于生

我们希望尽可能高效地执行下面的循环。我们有两台不同的机器,一台MIMD机器和一台SIMD机器

for (i=0; i<2000; i++)
    for (j=0; j<3000; j++)
        X_array[i][j] = Y_array[j][i] + 200;

对于(i=0;i来说,如果不做更多您没有指定的假设,那么几乎没有足够的信息来回答这个问题


使用SIMD将此问题矢量化并非易事,因为
X[i][j]
的数组索引与
Y[j][i]
的数组索引相反,因此问题在于生成数组的转置副本(并添加
+200
是的,SIMD可以提供帮助,但您需要随机播放和混合指令以及垂直添加,因此详细信息在很大程度上取决于ISA提供的随机播放和混合指令的详细信息。或者快速加载或收集指令

此外,还取决于编译器的智能程度,它是否使用SIMD指令。或者它是否可能加载一个向量并使用SIMD执行
+200
,然后使用标量分散结果?甚至将向量元素提取到内存的成本也取决于ISA。例如,对于x86,SSE2需要单独的洗牌来获得e元素您希望位于向量的底部。但是SSE4.1添加了
pextrq
,可以将qword
double
存储到内存中。但是它的AVX版本只能访问向量的低2个元素



多核与SIMD不是相互冲突的选择,它们是正交的。事实上,大多数现实世界中的多核CPU都有某种形式的SIMD,因为在创造多核CPU的复杂性之前,SIMD指令值得添加到单核

在4个CPU上运行标量代码通常会浪费数据并行性问题。在现实生活中,您可以使用SIMD将问题矢量化,然后(如果问题足够大)将其拆分为多个线程,以实现MIMD x SIMD乘法加速


使用多个线程访问同一数据的加速比可能不是线性的。这个问题只涉及每个数组元素一次,因此它可能是内存受限的。但是它有一个困难的访问模式。没有根据假设这个问题是ALU受限的,并且与内核数成线性比例。在实践中ce内核都将竞争读/写同一个RAM。或者它们的私有缓存都需要读取结果

通过仔细设计转置,您可能可以避免多个线程非常需要读取相同的缓存线

启动开销对于在实践中使用MIMD线程级并行也是非常重要的。也许您应该假设零开销,或者您正在以最小的同步成本对不同的阵列重复执行此操作?然后确保您可以假设零启动开销

(除非你说的是单核内的指令级并行。这是免费的。但你提到的是“4 CPU”当然,在现实生活中,通常只有在利用超标量和SIMD单核的低挂果实后,才值得构建多核,因此实际代码可能在每个核上每个时钟运行3个向量指令,每个指令在8个SIMD向量元素上运行)

e、 这就是你在四核Skylake CPU上得到的单精度
float
vectors


但问题是你需要计算指令的数量?

比较SIMD机器和MIMD机器上执行的指令数

for (i=0; i<2000; i++)
    for (j=0; j<3000; j++)
        X_array[i][j] = Y_array[j][i] + 200;
您如何知道有多少循环开销,或者编译器展开了多少

更重要的是,洗牌/混合指令是如何准确地设计来让您进行转置的


我想知道切换索引是否是一个错误,因为这是一个非常简单的问题,如果它只是一个没有转置的复制和添加,那么简单的垂直SIMD很容易解决。

这看起来像是家庭作业,因此家庭作业问题有望显示出解决方案的一些努力。

我们不能期望如此ers将给出一个解决方案。请编辑以显示已尝试过的内容。多核与SIMD不是相互冲突的选择,它们是正交的。事实上,大多数现实世界中的多核CPU都有某种形式的SIMD,因为SIMD指令值得添加到单核中,然后才值得创建多核CPU的复杂性。使用多线程通常只对大问题有意义,因为线程在大多数系统上都有大量的启动开销。您的4倍完美加速系数还假设线程不竞争内存带宽或任何东西。