c++ - Eigen3 矩阵乘法性能取决于处理器?

标签 c++ multithreading performance matrix-multiplication eigen

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

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

计算机 1:

英特尔酷睿 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

Eigen 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 中那么快吗?

最佳答案

感谢您的回答。

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

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

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

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

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

关于c++ - Eigen3 矩阵乘法性能取决于处理器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13799333/

相关文章:

c++ - 构造虚拟基类时的编译器行为

C++ 比较成员函数指针

java - 线程排序比非线程排序运行得慢

sql-server - 在根本不需要的情况下,对更大数据类型的使用进行性能测量的统计分析

从不同文件调用时,C++ __TIME__ 是不同的

c++ - 如何在 QTextStream 中退格 "write"?

java - Java如何正确添加同步

ASP.NET Page.Cache 与 Page.Application 存储用于数据同步?

javascript - 通过 framerate/requestAnimationFrame 确定元素是否在屏幕上

sql - 当 IN 子句有子查询时,为什么 SQL Server 执行群集扫描?