【问题标题】:Eigen3 matrix multiplication performance dependent of the processor?Eigen3 矩阵乘法性能取决于处理器?
【发布时间】:2012-12-10 10:44:06
【问题描述】:

上个月我一直在使用计算机矩阵乘法,并使用 openMP 和 eigen3 进行了一些测试。

测试是在以下机器上进行的:

计算机 1:

Intel Core i7-3610QM CPU @ 2,30GHz / 6 GB ddr3

计算机 2:

六核 AMD Opteron(tm) 处理器 2435 2.60 GHz(2 个处理器)/16 GB

对于 openMP,使用了以下矩阵-矩阵乘法算法:

void matrix4openmp(void)
{
    int j;

#pragma omp parallel for 
for (j=0;j<N; j+=2){
  double v1[N],v2[N];
    int i,k;
  for (i=0;i<N; i++){
     v1[i]=b[i][j];
     v2[i]=b[i][j+1];
  }

  for (i=0; i<N;i+=2){
     register double s00,s01,s10,s11;
     s00=s01=s10=s11=0.0;
     for (k=0;k<N;k++){
        s00 += a[i]  [k] * v1[k];
        s01 += a[i]  [k] * v2[k];
        s10 += a[i+1][k] * v1[k];
        s11 += a[i+1][k] * v2[k];
     }
     c[i]  [j]   =s00;
     c[i]  [j+1] =s01;
     c[i+1][j]   =s10;
     c[i+1][j+1]   =s11;
  }
}

结果如下:

_______________计算机 1__________计算机 2

顺序________232,75600___________536,21400

OpenMP____________2,75764____________7,62024

特征3_____________3,35090____________1,92970

*时间以秒为单位。

*矩阵大小分别为 2700 x 2500 和 2500 x 2700。

*顺序算法与 OMP 不同,它是 m-m 乘法的最简单版本,可以在此处查看:http://pastebin.com/Pc9AKAE8

*SSE2 指令已为 eigen3 测试激活。

*OpenMP 使用默认内核,这是 Windows 检测到的所有内核,包括虚拟内核。

如您所见,OpenMP 版本在第一台计算机 (i7) 上比 eigen3 版本更快。但是对于计算机 2(2x Opteron),eigen3 的性能完全胜过 OpenMP 版本以及在计算机 1 中进行的所有测试。

知道为什么我会得到这个结果,为什么 eigen3 在计算机 1 中的速度不如在计算机 2 中那么快吗?

【问题讨论】:

  • 你能让所有的实现都使用 SSE2 吗? Opteron 有更多更快的内核用于原始内存时钟泵送,这使得这成为一个明显不平衡的测试。我建议至少均衡指令集(通过编译)和使用的内核数量。 (taskset)。
  • @High Performance Mark 我忘了补充一点,顺序版本不使用我发布的相同算法,它使用最简单的版本,不使用任何优化。就是这个:pastebin.com/Pc9AKAE8 这就是为什么它可能要慢得多,因为它应该只使用内存而不是缓存和寄存器。
  • @Steve-o 我将尝试按顺序启用 SSE 和 OpenMP 并将其报告给您。使用的核心数是 openMP 的默认值,这是 windows 在每台机器中检测到的所有虚拟处理器(computer_1 中的 8 个,computer_2 中的 12 个)。当您的意思是“原始内存时钟泵送”时,您是在谈论 ram-cpu 数据传输吗?
  • @Steve-o 哪里有一些有趣的测试,所有测试都启用了相同数量的 CPU(4 个线程)和 SSE2:pastebin.com/mkWCicb7 现在这似乎更有意义了。似乎 i7 使用 8 个线程比使用 4 个线程要慢得多,因为它只有 4 个物理处理器。我可能会再次测试,将线程数设置为物理处理器的数量,而不是使用虚拟处理器进行计数。
  • 您应该牢记以下几点: 1. Eigen3 使用 OpenMP 内置了矩阵-矩阵乘积的并行化(如果您使用 -fopenmp 编译它) 2. 应使用编译器编译 Eigen启用优化(-O2 或 -O3)并禁用断言(-DNDEBUG)。

标签: c++ multithreading performance matrix-multiplication eigen


【解决方案1】:

感谢您的回答。

顺序和并行版本之间的巨大差异是由于使用了不同的算法。顺序版本使用通常的朴素 O(N^3) 没有任何优化,而并行版本是优化版本 - 使用块。使用相同的算法,顺序版本时间大约为 10(计算机 1)和 50(计算机 2)——抱歉应该将这些值放在第一篇文章中。

第一台和第二台计算机中 Eigen3 性能与 OpenMP 性能之间的差异似乎是由于启动的线程数与可用物理处理器的数量之间的差异。我们发现,如果启动的线程数大于可用的物理处理器数,Eigen3 的性能会变差,而 OpenMP 并非如此

在测试中,两种情况下启动的线程数等于处理器总数(虚拟 + 物理)。

在计算机 1 中,Eigen3 性能更差,因为总处理器的数量(虚拟 + 物理 - - 由于超线程)大于物理处理器的数量。

在计算机 2 中,Eigen3 性能更好,因为处理器的总数与物理处理器的数量相同。如果我们使用双倍的物理处理器数量作为线程数量,Eigen3 的性能也会下降,而 openMP 实际上会有所提高。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    • 2017-11-06
    • 2019-01-02
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多