2024年国科大-高性能计算编程-作业一

文章讨论了在Windows和MacOS上编译并测试作业代码homework1.cpp的过程,分析了不同优化级别下(O0-O3)的运行时间和编译器行为,发现MacOS上Clang编译器在O1及以上优化时删除了未使用的函数。作者还详细解析了各优化级别下的代码优化策略,尤其是向量化和循环展开对性能的影响。
摘要由CSDN通过智能技术生成

作业题目

提交内容一:平台信息

  • 本次作业在Windows平台及MacOs平台上均测试了homework1.cpp的运行,具体平台信息如下

Windows平台

  • 系统:Win11-23H2

  • CPU:i9-13900HX(x86)

  • 内存:64G

  • IDE:CLion

  • 编译器:MinGW

MacOs平台

  • 系统:MacOs-14.3
  • CPU:M2(arm)
  • 内存:16G
  • IDE:CLion
  • 编译器:Clang

提交内容二:代码运行时间

  • 本次作业分别在两个平台上使用-O0 -O1 -O2 -O3编译homework1.cpp,并记录四种优化条件下代码的运行时间,具体结果如下

Windows平台

-O0编译

-O1编译

-O2编译

-O3编译

数据总览
Win-MinGWVecadd Timing/usMatrix Multiply Timing/usPi Timing/us
-O0322425576024074
-O1266923103771001
-O2200923442741017
-O3200023588371651

MacOs平台

-O0编译

-O1编译

-O2编译

-O3编译

数据总览
Mac-ClangVecadd Timing/usMatrix Multiply Timing/usPi Timing/us
-O0885866611876147
-O1002358
-O2012390
-O3102592
  • 可以发现在Mac端,使用-O1及以上优化级别进行编译时,Vecadd Timing及Matrix Multiply Timing均为0us或1us,因此可能是这两个函数根本没被运行。查看代码发现,原实验代码中Vecadd和Matrix Multiply函数计算完c[1024*1024]及cc[1024*1024]后,这两个数组都没有再被使用过,因此可能是Clang编译器识别到这一情况后直接将这两个函数视为无用代码在编译时进行了删除。因此修改源代码,在计算完c[1024*1024]及cc[1024*1024]后分别输出一下c[0],让编译器在编译时不删除这两个函数的内容。以下是修改源代码后再次测试的结果

MacOs平台修改源码后再次测试

-O1编译

-O2编译

-O3编译

数据总览
Mac-ClangVecadd Timing/usMatrix Multiply Timing/usPi Timing/us
-O0885866611876147
-O1653221057991745
-O2581721059891564
-O3258521040091601

提交内容三:优化方法分析

  • 以Windows平台,Vecadd函数为例进行分析

-O0

  • 不进行任何优化

-O1

  • 在 -O0中,vecadd 函数的循环是这样的:
.L7:
  movq    -8(%rbp), %rax
  cmpq    40(%rbp), %rax
  jnb     .L6
  movq    -8(%rbp), %rax
  leaq    0(,%rax,8), %rdx
  movq    16(%rbp), %rax
  addq    %rdx, %rax
  movsd   (%rax), %xmm1
  movq    -8(%rbp), %rax
  leaq    0(,%rax,8), %rdx
  movq    24(%rbp), %rax
  addq    %rdx, %rax
  movsd   (%rax), %xmm0
  movq    -8(%rbp), %rax
  leaq    0(,%rax,8), %rdx
  movq    32(%rbp), %rax
  addq    %rdx, %rax
  addsd   %xmm1, %xmm0
  movsd   %xmm0, (%rax)
  addq    $1, -8(%rbp)
  jmp     .L7
.L6:
  movl    $0, %eax
  addq    $16, %rsp
  popq    %rbp
  ret
  • 在 -O1中,vecadd 函数的循环是这样的:
.L5:
  movsd  (%rcx,%rax,8), %xmm0
  addsd  (%rdx,%rax,8), %xmm0
  movsd  %xmm0, (%r8,%rax,8)
  addq    $1, %rax
  cmpq    %rax, %r9
  jne     .L5
.L4:
  movl    $0, %eax
  ret
  • 循环展开:在 -O1 中,循环体被简化了。在 -O0 中,我们看到了对索引的计算( leaq 0(,%rax,8), %rdx),然后使用这个索引来访问数组。在 -O1 中,这个计算被直接内联到循环体中,减少了对寄存器的依赖和循环控制的开销。
  • 寄存器使用:在 -O1 中,编译器对寄存器的使用进行了优化,相比于-O0更加高效
  • 循环简化:在 -O1 中,循环控制( addq $1, %rax ,cmpq %rax, %r9)和条件跳转( jne .L5)相较于-O0中的代码而言更加简化,这有助于提高循环的执行效率。

-O2

  • -O2的vecadd函数基本与-O1中一样,证明-O1已经对该函数进行了足够的简化,或该函数较为简单,无须再次优化

-O3

  • 在 -O2中,vecadd 函数的汇编代码是这样的:
.L6:
  movsd  (%rcx,%rax,8), %xmm0
  addsd  (%rdx,%rax,8), %xmm0
  movsd  %xmm0, (%r8,%rax,8)
  addq    $1, %rax
  cmpq    %rax, %r9
  jne     .L6
.L5:
  xorl    %eax, %eax
  ret
  • 在 -O3中,vecadd 函数的汇编代码是这样的:
.L7:
  movq    (%rcx,%rax), %xmm0
  movq    (%rdx,%rax), %xmm1
  movhpd  8(%rcx,%rax), %xmm0
  movhpd  8(%rdx,%rax), %xmm1
  addpd   %xmm1, %xmm0
  movlpd  %xmm0, (%r8,%rax)
  movhpd  %xmm0, 8(%r8,%rax)
  addq    $16, %rax
  cmpq    %rax, %r10
  jne     .L7
  movq    %r9, %rax
  andq    $-2, %rax
  cmpq    %rax, %r9
  je      .L5
  movsd   (%rcx,%rax,8), %xmm0
  addsd  (%rdx,%rax,8), %xmm0
  movsd   %xmm0, (%r8,%rax,8)
.L5:
  xorl    %eax, %eax
  ret
  • 向量化操作:在 -O3 中,编译器添加了 movhpd 指令的使用,这表明编译器可能在尝试利用 SSE2 指令集进行向量化操作。这可以显著提高数据处理的效率,因为它允许同时处理多个数据。
  • 循环展开:在 -O3 中,循环体被进一步展开,以减少循环控制的开销。例如,movhpd 指令用于同时加载和存储两个双字(64位)浮点数,这减少了内存访问次数。
  • 条件分支优化:在 -O3 中,编译器对条件分支进行了优化,例如通过使用 setnb 和 seta 指令来优化条件跳转。这有助于提高分支预测的准确性。
  • 循环控制逻辑:在 -O3 中,循环控制逻辑更加复杂,这表明编译器可能在尝试更精细地控制循环的执行,以减少不必要的计算和内存访问。

总结

  • -O0:不进行优化
  • -O1:主要对代码的分支、表达式、循环体等进行优化
  • -O2:尝试更多的寄存器级和汇编指令级的优化,增大调试难度
  • -O3:在O2的基础上对循环体等进行更多精细、激进的优化,可能会使汇编代码的逻辑更加复杂,加大精度的同时可能会增大运行时间及调试难度
  • Clang编译器的优化更为激进,会删除不影响程序运行的代码段(例如定义后未使用的变量等),因此在本次作业中需要修改源代码才能进行运行时间的测量,否则编译器会直接删除main函数中Vecadd以及Matrix Multiply函数的调用

自评分及理由

自评分

  • 10分

评分理由

  • 在Windows及MacOs双平台完成作业
  • 收集双平台数据并绘制总览图表
  • 根据汇编代码进行不同优化级别的优化方法分析
  • 分析Clang(Mac)进行-O1以上级别的编译时代码运行时间为0的原因
  • 对比分析MinGW(Win)及Clang(Mac)的优化策略
  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值