ffmpeg 8.1.2 は ARM64 版に替えても決定打にならなかった
ffmpeg 8.1.2 の x64 版と BtbN の ARM64 版を比べたら、x264 medium 720p は3.61秒対3.28秒。x64 が1.10倍遅いだけだった。
正直、拍子抜けした。winget で入れた ffmpeg.exe が x64 だと気づいたときは、これは遅いに決まっていると思ったのだ。Windows 11 Pro の ARM64 でエミュレーションが足を引っ張って、ネイティブの BtbN ビルドが素直に勝つ。そういう絵を勝手に描いていた。
測ってみたら、話はもっとややこしかった。x264 の medium で 720p に落とす処理は、たしかに ARM64 が少し速い。ところが x264 ultrafast の 1080p だと x64 のほうが速い。スケーリングだけを見る -f null では ARM64 がはっきり勝つ。どれかひとつを取り出せば「ネイティブが速い」とも「エミュレーションで十分」とも言えてしまう。残りの数字が全部それを裏切るのだけれど。
測定日は2026-06-30。マシンは Microsoft Surface Pro, 11th Edition、Snapdragon X 12-core X1E80100 @ 3.40GHz、メモリ 32GB の ARM64 Windows 環境だ。電源は AC につないだまま、電源プランは既定のバランスのまま触っていない。普段の作業状態から大きく外したくなかった。
まず winget 版の正体を見た
winget で入っていた実行ファイルは Gyan.FFmpeg 配下の ffmpeg-8.1.2-full_build にあった。パスを眺めても x64 か ARM64 かは分からない。パッケージ名だけで決めつけるとだいたい間違えるので、最初に実体を確認している。で、x64 だった。じゃあ ARM64 ネイティブ版を持ってきたらどうなるのか、という流れになる。
ARM64 版は BtbN/FFmpeg-Builds の winarm64-gpl zip を落として、中から ffmpeg.exe を取り出した。使ったコマンドはこれ。
curl.exe -L -s -o C:\Users\AKIRAS~1\AppData\Local\Temp\arm64lab_c\ff-arm64.zip https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-winarm64-gpl.zip
ダウンロードは7.8秒で終わり、zip は114800704バイト。展開した ARM64 版の ffmpeg.exe は C:\Users\AKIRAS~1\AppData\Local\Temp\arm64lab_c\ffmpeg-arm64\ffmpeg.exe に置いた。素材も同じ ARM64 版で作っている。testsrc2 の 1920x1080、30fps、20秒の合成映像を libx264 ultrafast で src.mp4 にしたものだ。生成に14.78秒かかって、できたファイルは38850889バイトだった。実写じゃないという点は、あとで効いてくる。
比べたジョブ
ジョブは3本に絞った。x264 medium で 720p へ落とす処理、x264 ultrafast の 1080p、それとエンコードをほぼ外してスケーリング結果を -f null に捨てる処理。この3つを x64 版と ARM64 版で3回ずつ回した。
この設計、正直に言って粗い。素材は実写ではなく testsrc2 の合成映像だ。1ジョブの実行時間も0.52秒から5.81秒に収まってしまっていて、プロセス起動やファイル I/O の比重がやたら大きい。反復も3回しかないから、中央値を出したところで安心できる代物ではない。それでもまず小さく測ってみたかった。
ffmpeg のビルドを差し替える動機があるかどうか、当たりをつけるだけなら悪くない。ただ1割の差を判定する用途にはまるで足りていなかった。これは測り終えてから気づいている。
runs_s をそのまま見る
中央値だけ並べると見通しはよくなる。でも今回それをやると危ない。ばらつきそのものが結果の一部だからだ。3回分の runs_s と fps_samples をそのまま載せる。
| ジョブ | ビルド | runs_s 全3回 | median_s | fps_samples |
|---|---|---|---|---|
| x264 medium 720p | x64 | 2.94 / 3.61 / 5.81 | 3.61 | 225 / 179 / 109 fps |
| x264 medium 720p | ARM64 | 3.94 / 2.24 / 3.28 | 3.28 | 206 / 289 / 261 fps |
| x264 ultrafast 1080p | x64 | 1.88 / 1.81 / 1.61 | 1.81 | 375 / 391 / 420 fps |
| x264 ultrafast 1080p | ARM64 | 2.18 / 5.20 / 1.86 | 2.18 | 458 / 120 / 567 fps |
| scale only null | x64 | 0.73 / 0.76 / 0.76 | 0.76 | 0 / 0 / 0 fps |
| scale only null | ARM64 | 0.55 / 0.52 / 0.53 | 0.53 | 0 / 0 / 0 fps |
x264 medium 720p は x64 が3.61秒、ARM64 が3.28秒。x64 が1.10倍遅い。
向きは予想どおり。でも差が小さい。3回の中には x64 の2.94秒もあれば ARM64 の3.94秒もあって、1回しか測っていなかったら逆の結論を書いていたと思う。この時点で勝ち負けを急ぐのはやめた。
意外だったのが x264 ultrafast 1080p のほう。中央値は x64 が1.81秒、ARM64 が2.18秒で、x64_slower_x は0.83倍。つまりこの条件では x64 が速い。ARM64 側の fps_samples は458 / 120 / 567 fps と暴れていて、同じ条件のはずなのに120fpsから567fpsまで振れている。この幅を見せられると、2.18秒という中央値もあまり信用できない。
scale only null だけは素直だった。x64 が0.76秒、ARM64 が0.53秒で、x64 が1.43倍遅い。エンコードを外してスケーリング寄りにすると、ネイティブ版が有利に見える。ただし fps_samples は全部0fps。ffmpeg の出力から拾える指標としては何の役にも立たなかった。
失敗したのは測り方のほう
一番大きな失敗は、測定単位が短すぎたことだと思う。20秒の素材を処理しているのに、ジョブ自体は2秒から4秒で終わってしまう。これだと ffmpeg.exe の起動、入力ファイルを開く時間、出力先の作成、OS のキャッシュ状態が全部混ざる。
反復3回も足りなかった。x264 ultrafast 1080p の ARM64 は runs_s が2.18秒、5.20秒、1.86秒で、最大と最小が2.80倍も違っている。fps_samples も120fpsから567fpsまで動いた。この振れ幅で1.10倍の差を性能差として扱うのは、さすがに無理がある。なぜもっと長い素材を用意しなかったのか、と自分でも思う。
もうひとつ勘違いしかけた。ARM64 ネイティブ対 x64 エミュレーションを、そのまま「エミュレーションのコスト」と読みそうになったのだ。でも libx264 は手書きアセンブリの最適化が厚い領域で、ARM64 ビルドと x64 ビルドでは使っているカーネルからして違う可能性がある。実際には CPU 命令、x264 の実装、ffmpeg のビルド設定、Windows のエミュレーション、I/O の揺れが全部重なっている。翻訳コストだけを切り出した測定にはなっていない。
ここに気づくまで「ネイティブなら勝つはず」という前提で数字を見ていた。数字のほうがその期待を崩してくれた。結果がまちまちだったこと自体を結論として扱うのが正しかったのだと思う。
手元の運用は変えない
この数字だけで ffmpeg を ARM64 版に置き換える気には、正直ならない。x264 medium 720p の3.61秒対3.28秒は差が小さいし、x264 ultrafast 1080p では x64 が1.81秒で勝っている。scale only null の0.76秒対0.53秒は ARM64 が強いけれど、普段の用途がそこだけに寄るわけでもない。
というわけで、手元は winget 版のままにしておく。パッケージ更新が楽なのも大きい。今回の範囲では、x64 エミュレーションが明確なボトルネックだとまでは読めなかった。むしろ Surface Pro 11th Edition の Windows 11 ARM64 は、x64 の ffmpeg でも思っていたより普通に動いてしまう。ちょっと悔しい。
次にやるなら実写素材で長時間のエンコードを測り直したい。最低でも数分単位の入力を使って、反復も増やして、最初の1回はウォームアップとして捨てる。2026年6月30日の小さな実験としては、ARM64 版に替えれば常に速くなるという期待をいったん引っ込めるのに十分だった。