🌠

FFmpeg 8?でAVX-512のパフォーマンスを見てみる

に公開

FFmpeg 8.0ではAVX-512の命令セットに最適化されたという記載がありました。AVX2との比較などはありましたが、単純にFFmpeg 7.1.1からどう変わったかの方が気になりましたので、FFmpegの7と8で比較をしてみようと思いました。
なおFFmpeg 8.0というリリースはまだされていないので、gitの最新ソースを現状8(相当)としてビルドしています。読み替えて頂ければ幸いですが、tagをみると実際は7.2devになるのかな…

環境

サーバ情報

まずはAVX-512に対応したCPUが必要なので、AWSのEC2で同一インスタンスを2個立ち上げて見てみました。

$ gcc -march=native -Q --help=target | grep march
  -march=                               skylake-avx512

$ grep -o 'avx512[^ ]*' /proc/cpuinfo | sort | uniq
avx512bw
avx512cd
avx512dq
avx512f
avx512vl

skylakeで名前にもavx512がついている通り、avx512にも対応している事が確認できます。

環境準備

今回はlibvirtにて、以下の構成でセットアップします。

  • AWS EC2
  • xlarge
    • vCPU x4
    • Memory 16GB

ソフトウェア

エンコードに関してはコンパイルの都合上、FFmpeg 8もFFmpeg 7.1.1もどちらもSVT-AV1 2.3.0を使用しています。参考までに、FFmpeg 8とSVT-AV1 3.1.0のテストも一度だけ行っています。

セットアップ

共通

dnf -y update
dnf -y groupinstall "Development Tools"
dnf -y install cmake

cd /usr/local/src

curl -LO https://www.nasm.us/pub/nasm/releasebuilds/2.16.03/nasm-2.16.03.tar.gz
tar zxf nasm-2.16.03.tar.gz
cd nasm-2.16.03
./configure && make && make install
cd ..

export CFLAGS="-O3 -march=skylake-avx512 -mavx512f -mavx512vl -mavx512bw -mavx512dq -mavx512cd"
export CXXFLAGS="$CFLAGS"

git clone --depth 1 https://gitlab.com/AOMediaCodec/SVT-AV1.git -b v2.3.0 svtav1
cd svtav1/Build
cmake .. \
 -DCMAKE_BUILD_TYPE=Release \
 -DCMAKE_C_FLAGS="$CFLAGS" \
 -DCMAKE_CXX_FLAGS="$CXXFLAGS" \
 -DENABLE_AVX512=ON \
 -DBUILD_SHARED_LIBS=OFF
make && make install

AVX-512に対応する為にはnasmの2.15以上が推奨になりますが、ディストリビューションによっては古いバージョンの可能性があります。ソースから最新版をビルドすることをお勧めします。
SVT-AV1は、FFmpegの比較の為にいれるので敢えてFFmpeg 7.1.1でも通るようにバージョンを落としています。今回は念のため-DENABLE_AVX512=ONでAVX-512を明示的にONにしていますが、通常は何もしなくても検出してくれます。

FFmpeg 8.0(相当)

git clone --depth 1 https://git.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
./configure \
 --enable-gpl \
 --enable-libsvtav1 \
 --extra-cflags="$CFLAGS -I/usr/local/src/svtav1/Source/API" \
 --extra-cxxflags="$CXXFLAGS" \
 --extra-ldflags="-L/usr/local/src/svtav1/Bin/Release"
make && make install

FFmpeg 7.1.1

git clone --depth 1 https://git.ffmpeg.org/ffmpeg.git -b n7.1.1 ffmpeg
cd ffmpeg
./configure \
 --enable-gpl \
 --enable-libsvtav1 \
 --extra-cflags="$CFLAGS -I/usr/local/src/svtav1/Source/API" \
 --extra-cxxflags="$CXXFLAGS" \
 --extra-ldflags="-L/usr/local/src/svtav1/Bin/Release"
make && make install

このテストの為だけのビルドなので最低限のみにしています。

テスト

Video Filter Test

timeコマンドで時間を計測してみました。表に乗っているのはuserの値です。

time ffmpeg -i big_buck_bunny_1080p_stereo.avi -vf "{video filter}" -f null -
FFmpeg 8 FFmpeg 7
select=gt(scene,0.4) 0m53.937s 0m47.325s
scale=640:360,hqdn3d 2m47.179s 2m37.142s
nlmeans=s=2:r=7:p=5 113m47.075s 111m2.345s

AV1 Encode Test

time ffmpeg -i big_buck_bunny_1080p_stereo.avi -c:v libsvtav1 -preset 8 -crf 30 -b:v 0 test.ivf
FFmpeg 8 FFmpeg 7
SVT-AV1 2.3.0 35m43.237s 29m0.870s
SVT-AV1 3.1.0 24m16.989s

結果

実際に色々やってみたけど、(誤差の範囲ですが)FFmpeg 7の方が早いという結果に。もちろん一部の機能の更新という事でFFmpeg全体が高速化したとは思っていないですが、VideoFilter系はある程度差が出るものがあるかなとは思っていました。
参考までに、最適化という意味でFFmpeg 8とSVT-AV1 3.1.0のエンコードテストをしたらこちらは爆速でした。まあ正直これだけでもアップグレードする意味はあるかもしれませんね。

計測

IntelのVTune Profilerを使用して実際に解析まで行おうとしていたんですが、EC2やlibvirtなど仮想環境ではうまく動かず、こちらもちょっと動くまで調査してみようと思います。
perfは動いたのでFlameGraphを使ってSVGまで出してみたんですが、こちらもあまり効果はなしでした。実際にリリースされたらデバック用ビルドにして可視化してみようと思います。

まとめ

当たり前ですが、いったん正式に8.0がリリースされるのを待とうと思います。
あとAVX2やAVX-512に関して、FFmpegの内部処理について、もうちょっと勉強が必要だと感じました。日々勉強、精進します。

参考


https://voice.stream.co.jp/

Discussion