大多数编译器都会优化 MATMUL(TRANSPOSE(A),B) 吗?

2024-04-02

In a Fortran program, I need to compute several expressions like M · v, MT · v, MT · M, M · MT, etc ... Here, M and v are 2D and 1D arrays of small size (less than 100, typically around 2-10)

我想知道是否写MATMUL(TRANSPOSE(M),v)将在编译时展开为一些代码,其效率如下MATMUL(N,v), where N显式存储为N=TRANSPOSE(M)。我对具有“强”优化标志(例如 -O2、-O3 或 -Ofast)的 g​​nu 和 ifort 编译器特别感兴趣。


下面您可以看到各种方法的几个执行时间。

system:

  • 英特尔(R) 酷睿(TM) i5-6500T CPU @ 2.50GHz
  • 缓存大小:6144 KB
  • 内存:16MB
  • GNU Fortran (GCC) 6.3.1 20170216(红帽 6.3.1-3)
  • 艾福特(IFORT) 18.0.5 20180823
  • BLAS :对于gnu编译器,使用的blas是默认版本

汇编:

[gnu] $ gfortran -O3 x.f90 -lblas
[intel] $ ifort -O3 -mkl x.f90

执行:

[gnu] $ ./a.out > matmul.gnu.txt
[intel] $ EXPORT MKL_NUM_THREADS=1; ./a.out > matmul.intel.txt

为了使结果尽可能中立,我用完成的一组等效操作的平均时间重新调整了答案。 我忽略了线程。

矩阵乘向量

比较了六种不同的实现:

  1. manual: do j=1,n; do k=1,n; w(j) = P(j,k)*v(k); end do; end do
  2. matmul: matmul(P,v)
  3. blas N:dgemv('N',n,n,1.0D0,P,n,v,1,0,w,1)
  4. matmul 转置: matmul(transpose(P),v)
  5. matmul-转置-tmp: Q=transpose(P); w=matmul(Q,v)
  6. blas T: dgemv('T',n,n,1.0D0,P,n,v,1,0,w,1)

在图 1 和图 2 中,您可以比较上述情况的时序结果。总的来说,我们可以说临时的使用在两个方面gfortran and ifort不建议。两种编译器都可以优化MATMUL(TRANSPOSE(P),v)好多了。而在gfortran, 实施MATMUL比默认的 BLAS 更快,ifort清楚地表明mkl-blas是比较快的。

enter image description here figure 1: Matrix-vector multiplication. Comparison of various implementations ran on gfortran. The left panels show the absolute timing divided by the total time of the manual computation for a system of size 1000. The right panels show the absolute timing divided by n2 × δ. Here δ is the average time of the manual computation of size 1000 divided by 1000 × 1000.

enter image description here figure 2: Matrix-vector multiplication. Comparison of various implementations ran on a single-threaded ifort compilation. The left panels show the absolute timing divided by the total time of the manual computation for a system of size 1000. The right panels show the absolute timing divided by n2 × δ. Here δ is the average time of the manual computation of size 1000 divided by 1000 × 1000.

矩阵乘以矩阵

比较了六种不同的实现:

  1. manual: do l=1,n; do j=1,n; do k=1,n; Q(j,l) = P(j,k)*P(k,l); end do; end do; end do
  2. matmul: matmul(P,P)
  3. blas N:dgemm('N','N',n,n,n,1.0D0,P,n,P,n,0.0D0,R,n)
  4. matmul 转置: matmul(transpose(P),P)
  5. matmul-转置-tmp: Q=transpose(P); matmul(Q,P)
  6. blas T: dgemm('T','N',n,n,n,1.0D0,P,n,P,n,0.0D0,R,n)

在图 3 和图 4 中,您可以比较上述情况的时序结果。与向量情况相反,仅建议 gfortran 使用临时变量。而在gfortran, 实施MATMUL比默认的 BLAS 更快,ifort清楚地表明mkl-blas是比较快的。值得注意的是,手动实现相当于mkl-blas.

enter image description here figure 3: Matrix-matrix multiplication. Comparison of various implementations ran on gfortran. The left panels show the absolute timing divided by the total time of the manual computation for a system of size 1000. The right panels show the absolute timing divided by n3 × δ. Here δ is the average time of the manual computation of size 1000 divided by 1000 × 1000 × 1000.

enter image description here figure 4: Matrix-matrix multiplication. Comparison of various implementations ran on a single-threaded ifort compilation. The left panels show the absolute timing divided by the total time of the manual computation for a system of size 1000. The right panels show the absolute timing divided by n3 × δ. Here δ is the average time of the manual computation of size 1000 divided by 1000 × 1000 × 1000.


使用的代码:

program matmul_test

  implicit none

  double precision, dimension(:,:), allocatable :: P,Q,R
  double precision, dimension(:), allocatable :: v,w

  integer :: n,i,j,k,l
  double precision,dimension(12) :: t1,t2

  do n = 1,1000
     allocate(P(n,n),Q(n,n), R(n,n), v(n),w(n))
     call random_number(P)
     call random_number(v)

     i=0

     i=i+1
     call cpu_time(t1(i))
     do j=1,n; do k=1,n; w(j) = P(j,k)*v(k); end do; end do
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     w=matmul(P,v)
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     call dgemv('N',n,n,1.0D0,P,n,v,1,0,w,1)
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     w=matmul(transpose(P),v)
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     Q=transpose(P)
     w=matmul(Q,v)
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     call dgemv('T',n,n,1.0D0,P,n,v,1,0,w,1)
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     do l=1,n; do j=1,n; do k=1,n; Q(j,l) = P(j,k)*P(k,l); end do; end do; end do
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     Q=matmul(P,P)
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     call dgemm('N','N',n,n,n,1.0D0,P,n,P,n,0.0D0,R,n)
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     Q=matmul(transpose(P),P)
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     Q=transpose(P)
     R=matmul(Q,P)
     call cpu_time(t2(i))

     i=i+1
     call cpu_time(t1(i))
     call dgemm('T','N',n,n,n,1.0D0,P,n,P,n,0.0D0,R,n)
     call cpu_time(t2(i))

     write(*,'(I6,12D25.17)') n, t2-t1
     deallocate(P,Q,R,v,w)
  end do

end program matmul_test
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

大多数编译器都会优化 MATMUL(TRANSPOSE(A),B) 吗? 的相关文章

随机推荐

  • UIScrollView - (bounces = NO) 似乎覆盖 (pagingEnabled = YES)

    我有一个带有分页功能的 UIScrollView 因此带有 UIPageControl 并在页面之间左右拖动 轻拂的典型模型 并且我的工作正常 奇怪的是 当我想摆脱弹跳 这样就看不到左右两侧UI后面的黑色 时 突然分页不再起作用了 换句话说
  • 在 Storyboard 中实现视频视图

    我想构建简单的视频应用程序 可以查看用户添加的 YouTube 链接中的视频 我没有找到 VideoView 我的意思是如果图像视图用于图像 那么 UIView 用于视频 原库中没有执行视频观看功能的对象 但你可以导入MediaPlayer
  • 如何在 Python BaseHTTPRequestHandler 中处理分块编码?

    我有以下简单的 Web 服务器 利用 Pythonhttp module import http server import hashlib class RequestHandler http server BaseHTTPRequestH
  • 为什么选择 XML 而不是属性文件来进行 Log4J 配置?

    是否有任何理由在 Log4J 配置中使用 XML 而不是属性文件 有一个有趣的讨论这篇博客中两者的优点 http www laliluna de log4j tutorial html 以下部分摘自该博客 属性可以由属性文件或 XML 文件
  • fortran 77 到 fortran 90 的转换器软件 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有 fortran 77 编码 但我想转换为 fortran 90 在哪里可以下载转换器软件 这是我帮
  • Pandas json_normalize 因 JSON 中的空值而失败

    我有以下从外部网络服务获得的 json text id 1 name abc address flat 123 city paris street null error null 现在我想从这个 json 创建数据框 当我尝试下面时 fro
  • 无法解析模块ReactNativeEventEmitter

    将 React Native 从 0 29 升级到 0 30 后 我收到此错误消息 我多次删除了node modules 然后再次安装它们 清除了watchman缓存并npm start reset cache 我也在新项目上尝试过使用re
  • 将日期传递给 package.json 脚本

    我有一个正在尝试设置的部署脚本 我正在尝试将名为 DEPLOY DATE 的环境变量设置为等于现在 scripts deploy kubectl set env deploy api DEPLOY DATE date 问题是这只是将 DEP
  • 在linux中找不到syscall_table_32.S文件

    我正在使用linux headers 2 6 32 21虚拟机上的包 我要编写一个新的系统调用 我找到了其他文件来写入系统调用的缩写 但我找不到这个syscall table 32 S in arch x86 kernel 目录 请帮助我如
  • 将日期 yyyyMMdd 转换为 system.datetime 格式[重复]

    这个问题在这里已经有答案了 可能的重复 如何将日期从 yyyyMMdd 格式转换为 mm dd yyyy 格式 https stackoverflow com questions 4712335 how to convert date fr
  • 如何通过点击JButton来添加JPanel?

    我正在尝试创建一个小型 GUI 它有 2 个 JButtons 和 2 个 JPanels 每个 JPanels 上都有一些绘图动画 默认情况下 它必须显示第一个 JPanel 通过单击第二个 JButton 我想看到第二个 JPanel
  • 无法读取未定义的属性“thisCompilation”-react-scripts-ts

    我使用以下说明创建了一个完全空白的新项目 https developer microsoft com en us fabric get started https developer microsoft com en us fabric g
  • 在 Tensorflow 模型中添加低层

    尝试开发一些转移学习算法 我使用一些经过训练的神经网络并添加层 我正在使用 Tensorflow 和 python 在 Tensorflow 中使用现有图似乎很常见 导入图 例如使用元图 然后通过添加节点来设置新的高层 例如 我找到了这段代
  • 意外标记“(”附近出现语法错误

    下面是我的代码 它一直告诉我第 10 行导致了这个 意外标记 附近的语法错误 但我不明白为什么 我正在添加到已经编写的代码中 但它说有的部分错误不是我添加的内容的一部分 所以我对为什么会收到此错误感到非常困惑 此外 我想要一个关于此错误实际
  • 具有 2 个不同 .pem 密钥的 2 个服务器之间的 scp 命令

    我想使用 scp 和 2 个不同的 pem 密钥将文件夹从服务器 A 传输到服务器 B 这是最好的方法吗 它是否真的有效 scp i Documents server1 pem r email protected cdn cgi l ema
  • 在提取/替换操作期间保留对象属性的方法

    最近我在我的R代码中遇到了以下问题 在接受数据框作为参数的函数中 我需要添加 或替换 如果存在 一列 其中包含根据数据框原始列的值计算的数据 我编写了代码 但测试显示数据框提取 替换操作 我用过 结果是对象的特殊 用户定义 属性丢失 在意识
  • 使用 application/x-www-form-urlencoded 的 POST 请求

    后端开发人员在 POST 请求中给出了这些说明 路线 url app name controller action 控制器和操作应该是小写字母 API测试链接 http 请求应使用 POST 方法 参数应通过请求内容正文 FormUrlEn
  • 客户端语言

    我不是网络程序员 所以请原谅我的无知 当谈到服务器端编程时 我们有很多可用的技术 例如 PHP ASP net JSP 等 然而 说到客户端脚本 我只听说过 JavaScript 和 AJAX 也许您还可以包含 Java Applet 因为
  • 使用 PHP 将文件夹重命名为子文件夹

    我正在尝试通过重命名来移动文件夹 test1 和 test2 文件夹均已存在 rename test1 test2 xxx1 xxx2 我得到的错误是 重命名 没有这样的文件或目录 我认为这是因为目录 xxx1 不存在 我怎样才能移动 te
  • 大多数编译器都会优化 MATMUL(TRANSPOSE(A),B) 吗?

    In a Fortran program I need to compute several expressions like M v MT v MT M M MT etc Here M and v are 2D and 1D arrays