不同的 ISA 二进制分析结果矛盾
Different ISA binary profiling results contradiction
我正在分析我用 CPP 编写的针对 RISC 架构的代码。我有两个二进制文件,一个是为 x86 生成的,另一个是为 RISC-V 生成的。我已经使用 perf 和 gprof 完成了分析。根据 RISC 和 CISC 体系结构理论,但我从 perf 结果中得到的是矛盾的。谁能告诉我这里出了什么问题。
性能结果:
'./unit_tests'CISC 的性能计数器统计信息:
180,899022 task-clock (msec) # 0,885 CPUs utilized
7 context-switches # 0,039 K/sec
2 cpu-migrations # 0,011 K/sec
1.350 page-faults # 0,007 M/sec
588.853.057 cycles # 3,255 GHz
863.377.707 instructions # 1,47 insn per cycle
157.440.034 branches # 870,320 M/sec
992.067 branch-misses # 0,63% of all branches
0,204509183 seconds time elapsed
'./unit_tests'RISC 的性能计数器统计信息:
693,264322 task-clock (msec) # 0,999 CPUs utilized
28 context-switches # 0,040 K/sec
1 cpu-migrations # 0,001 K/sec
2.400 page-faults # 0,003 M/sec
2.320.185.432 cycles # 3,347 GHz
5.467.630.410 instructions # 2,36 insn per cycle
960.171.812 branches # 1385,001 M/sec
7.038.808 branch-misses # 0,73% of all branches
0,693978844 seconds time elapsed
从上面的结果可以看出,RISC 的运行时间比 CISC 多,而且 RISC 的 insn per cylce 也更多。我想知道为什么会这样。如果我遗漏了什么或对结果的解释有误,有人可以告诉我吗?
您正在分析 qemu 解释/模拟 RISC-V,而不是 QEMU 中的 RISC-V“访客”代码。 QEMU 不能那样做;它不是任何东西的 cycle-accurate 模拟器。
这比最初为 x86-64 编译的本机代码更慢并且需要更多的指令。
在 RISC-V 二进制文件上使用 binfmt_misc 透明地 运行 qemu-riscv64
使得 ./unit_tests
完全等同于 qemu-riscv64 ./unit_tests
您的测试结果证明了这一点:perf stat qemu-riscv64 ./unit_tests
给您的结果与您的问题大致相同。
有点相关:Modern Microprocessors A 90-Minute Guide! 有一些关于 CPU 管道如何工作的详细信息。 RISC 并不总是比现代 x86 CPUs 更好。他们使用足够多的晶体管来 运行 x86-64 编码速度很快。
您实际上会期望来自 RISC CPU 的相同工作的总指令更多,只是不会 那么多指示。比如 1.1 倍或 1.25 倍?
性能取决于微体系结构,而不仅仅是指令集。 IPC 和总时间或周期完全取决于微体系结构在寻找 instruction-level 并行性方面的积极性。现代英特尔设计在这方面是最好的,即使在相当密集的 CISC x86 代码中 memory-source 指令很常见。
我正在分析我用 CPP 编写的针对 RISC 架构的代码。我有两个二进制文件,一个是为 x86 生成的,另一个是为 RISC-V 生成的。我已经使用 perf 和 gprof 完成了分析。根据 RISC 和 CISC 体系结构理论,但我从 perf 结果中得到的是矛盾的。谁能告诉我这里出了什么问题。
性能结果:
'./unit_tests'CISC 的性能计数器统计信息:
180,899022 task-clock (msec) # 0,885 CPUs utilized
7 context-switches # 0,039 K/sec
2 cpu-migrations # 0,011 K/sec
1.350 page-faults # 0,007 M/sec
588.853.057 cycles # 3,255 GHz
863.377.707 instructions # 1,47 insn per cycle
157.440.034 branches # 870,320 M/sec
992.067 branch-misses # 0,63% of all branches
0,204509183 seconds time elapsed
'./unit_tests'RISC 的性能计数器统计信息:
693,264322 task-clock (msec) # 0,999 CPUs utilized
28 context-switches # 0,040 K/sec
1 cpu-migrations # 0,001 K/sec
2.400 page-faults # 0,003 M/sec
2.320.185.432 cycles # 3,347 GHz
5.467.630.410 instructions # 2,36 insn per cycle
960.171.812 branches # 1385,001 M/sec
7.038.808 branch-misses # 0,73% of all branches
0,693978844 seconds time elapsed
从上面的结果可以看出,RISC 的运行时间比 CISC 多,而且 RISC 的 insn per cylce 也更多。我想知道为什么会这样。如果我遗漏了什么或对结果的解释有误,有人可以告诉我吗?
您正在分析 qemu 解释/模拟 RISC-V,而不是 QEMU 中的 RISC-V“访客”代码。 QEMU 不能那样做;它不是任何东西的 cycle-accurate 模拟器。
这比最初为 x86-64 编译的本机代码更慢并且需要更多的指令。
在 RISC-V 二进制文件上使用 binfmt_misc 透明地 运行 qemu-riscv64
使得 ./unit_tests
完全等同于 qemu-riscv64 ./unit_tests
您的测试结果证明了这一点:perf stat qemu-riscv64 ./unit_tests
给您的结果与您的问题大致相同。
有点相关:Modern Microprocessors A 90-Minute Guide! 有一些关于 CPU 管道如何工作的详细信息。 RISC 并不总是比现代 x86 CPUs 更好。他们使用足够多的晶体管来 运行 x86-64 编码速度很快。
您实际上会期望来自 RISC CPU 的相同工作的总指令更多,只是不会 那么多指示。比如 1.1 倍或 1.25 倍?
性能取决于微体系结构,而不仅仅是指令集。 IPC 和总时间或周期完全取决于微体系结构在寻找 instruction-level 并行性方面的积极性。现代英特尔设计在这方面是最好的,即使在相当密集的 CISC x86 代码中 memory-source 指令很常见。