世界を動かす技術を、日本語で。

FFmpegアセンブリ言語レッスン

概要

  • FFmpeg School of Assembly Language の紹介
  • 必要な前提知識と学習内容の概要
  • レッスン構成と今後の課題の説明
  • Discordサーバー でのサポート案内
  • 利用可能な翻訳情報の案内

FFmpeg School of Assembly Language 概要

  • FFmpeg School of Assembly Language は、アセンブリ言語の基礎を学ぶための教材
  • FFmpeg 内でのアセンブリ言語の書き方を中心に解説
  • コンピュータ内部の仕組みを理解するための実践的な知識の習得
  • C言語(特にポインタ) の知識が必須
  • 高校数学(スカラーとベクトル、加算・乗算など)の基礎知識が推奨

レッスンと課題

  • 各レッスンごとに対応した 課題 (今後追加予定)を用意
  • レッスン終了時には FFmpeg へのコントリビュートが可能なレベルを目指す
  • 学習進捗に応じて 実践的なスキル の習得

サポートとコミュニティ

  • 質問や疑問点への対応として Discordサーバー を用意
    • サーバーURL: https://discord.com/invite/Ks5MhUhqfB
  • 学習者同士の交流や情報共有の場

翻訳と多言語対応

  • フランス語スペイン語 の翻訳版READMEを提供
  • 多様な言語環境に対応した学習サポート

Hackerたちの意見

FFMPEGがどれだけの規模で動いてるのか、想像もつかないよ。ちょっとした改善でも、何千時間もの計算時間が節約されるんだろうね。めちゃくちゃ役立つプロジェクトだ。

パフォーマンスへのこだわりは素晴らしいことだね。もしすべてのプロジェクトが同じようにこだわってたら、想像してみてよ。

でも、ちゃんとしたAPI(従来の意味で、SaaSじゃなくて)を持ってたらいいな。自分でプログラミング言語みたいなコマンドラインを理解しなくちゃいけないのはちょっと面倒だよね…。

前の議論 2025-02-22、コメント数222: https://news.ycombinator.com/item?id=43140614

nasmのマクロプリプロセッサがひどく使われてるね。別のアセンブラに移行するのは大変そうだ。

どこに?あのレッスンにはほとんどコードがないじゃん。

なんで移行するの?

思ってたよりも面白い。特化したチュートリアルは本当に良いね。

どうやってこれらのアセンブリ命令を異なるCPU間でポータブルにしてるんだろう?

そうだね、x86-64だけだよ。

一般的なCのフォールバックがあると思うけど、それがベースラインにもなるね。でも、大きな(ターゲットの)アーキテクチャには、アーキテクチャごとに手書きのアセンブリバージョンがあるよ。

最適でないコンパイラ生成のアセンブリによって引き起こされるホットスポットを特定する実際のプロセスってどうなってるの?アーキテクチャ特有のアセンブリの代わりに、手書きのコンパイラ中間表現(LLVM IR)を書く意味ってあるのかな?

普通は、vtuneやuprofみたいなツールを使ってISAレベルでベンチマークのホットスポットを分析するよ。ARM用のそんなツールについては全然わからないけど。 > アーキテクチャ特有のアセンブリの代わりに手書きのコンパイラ中間表現(LLVM IR)を書く意味ってあるのかな?私の経験では、あまりないね。手書きのアセンブリを結構やったけど、それはアーキテクチャ特有の問題に対処する時だけだよ。他のことはCで書けばいいし(Cのセマンティクスで表現できないエッジケースに当たることもあるけど、それは稀だし)。例えば、CやC++のコンパイラは、一般的に最適化されたコードを書くのが本当に得意なんだ。彼らが苦手なところは、ベクトル化されたコードみたいに、アルゴリズムを再設計して高速なベクトル命令を使えるようにする必要がある場合で、そうなったらコンパイラのインストリンシックを使わなきゃいけないし、それでもコンパイラのインストリンシックが悪いコード生成につながることもある。だから、結局はアセンブリで書くことになって、レジスタの割り当てやアウトオブオーダー命令みたいなコンパイラが気にすることについて賢くなる必要があるんだ。でも、この領域に入ると、手書きのアセンブリがコンパイラが出力するものより「良い」かどうかを一目で判断するのは無理なんだよね(「良い」の基準は人それぞれだけど)。測定してベンチマークを取らないといけないし、そのベンチマークは意味のあるものでなきゃダメなんだ。

手書きのコンパイラ中間表現(LLVM IRなど)を、アーキテクチャ特有のアセンブリの代わりに書くのは意味があるの? いや、あんまり。手書きのアセンブリに手を伸ばす理由はいくつかあって、どのケースでもIRは正しい選択じゃないんだ。もしベクターコードを確保するのが目的なら、まずはループに明示的なベクタライズプラグマを付けてみるのが一番の選択肢だよ。それがダメなら、次は汎用またはアーキテクチャ特有のベクターインストリンシックを使うか、SIMT風のベクターコードを書くための言語であるISPCみたいなものに飛びつくことになる。IRに飛びついても、このケースでは特に得るものはないよ。インストリンシックがコードを満たしてくれるからね。もしコンパイラのレジスタ割り当てや命令選択の最適化の問題を回避するのが目的なら… IRで書こうとすると、コンパイラがあなたが書いた正確なシーケンスを元のコードが生成するのと全く同じシーケンスに再正規化する可能性が非常に高くなるよ。コンパイラのIRはコードに何も追加しないし、ただ不安定で使いにくいインターフェースの余分なレイヤーを作るだけなんだ。この場合、手書きのアセンブリのベストバージョンを作るには、結局書きたかったアセンブリをそのまま書くのが一番だよ。

だから、ここでの主な問題は人々が思っているものとは違うんだ。一般的には「最適でないアセンブリ」じゃないし、少なくともCコンパイラから合理的に期待できるものではないよ。要因はこんな感じかな:- 特化:ループの普通のC実装はすでに decent だし、asm/SIMDバージョンは特定のハードウェアプラットフォーム用に追加されている。異なるプラットフォームには異なるSIMD機能があるから、一般化するのは難しい。- 予測可能性:ユーザーは異なるコンパイラのバージョンを使っているから、良いものがあってもみんながそれを使うわけじゃない。- 最適化の難しさ:Cのメモリモデルは特に最適化を難しくするんだ。なぜなら、ビデオは char * で、char * はすべてをエイリアスするから。さらに、コンパイラがこれのために追加する2種類の機能(インストリンシックと自動ベクタ化)はお互いに干渉して、何もないより悪化させることもある。- センス:SIMDを書くためのより良いポータブルな言語を想像できるかもしれないけど、Cはそれじゃない。そして、インテルのCでインストリンシックを使うのもそれじゃない。なぜなら、彼らのものはマイクロソフトによって発明されたもので、何事にも全く美的センスがなかったことで有名だから。アセンブリはCよりも読みやすいよ。だって、全てが _mm_movemask_epi8 みたいな名前の関数呼び出しになるから。

大好き!これを書くために時間を取ってくれてありがとう。もっと多くの人が貢献するきっかけになるといいな。

これがNASMみたいな実際のアセンブラで例を実行するための簡単な紹介から始まっていればよかったのに。

GitHubリポジトリにFFmpegアセンブリレッスンに必要な数学のレッスンを含めたらどう?全部一箇所にまとめておけば、みんな始めやすくなると思うよ :)

NTAだけど、もし読者がCプログラミングの基本的な理解しか持っていなくて、ビデオコーデックに貢献したいと思っているなら、クーリー/タキーアルゴリズムがどう機能するかを理解するために、かなりのことを学ばなきゃいけないよ。それすら基本的な部分に過ぎないけどね。

プロジェクトでの苦労から得られた知恵の珠を読むことを期待してたんだけど、これがffmpegとどう関係するのかが全然わからない。見た数章は、アセンブリ言語の一般的なイントロみたいな感じだった。