プログラミング
BSD Makeエクストラバガンザ:bmakeでのマンデルブロ集合
BSD Make extravaganza: Mandelbrot Set In bmake (github.com)
要約
この記事は、BSDのmakeビルドシステムのみを使用してマンデルブロ集合のレンダラーを実装したプロジェクトについて説明しています。著者は、makeの計算能力の限界を探求し、バイナリを一切呼び出さずに、加算、減算、乗算、除算といった基本的な算術演算をmakeの機能で実現しました。このレンダラーは非常に非効率的ですが、makeの汎用性を示すユニークなデモンストレーションとなっています。
全文翻訳
最初のミニブロブ、レンダリングに12時間。1000x250 z=32, it=64, re=-1.777 im=0 BSD Makeエクストラバガンザ。
FreeBSDのportsシステムを使い、そのmakefilesの多くとmake(1)のマニュアルページを大量に読んだ後、その言語が計算的に万能であることに気づきました。この気づきを得てから、視覚的なデモンストレーションを書き、makeをその限界までプッシュしたいという衝動を抑えることができませんでした。
マンデルブロ集合のレンダラーは、以前にそれを設計されていない場所に押し込む経験があったため、私にとって自然な選択でした。また、基本的な要素を多く必要とする、十分に包括的なプログラムであり、デモンストレーションの目的に適した計算負荷があります。
こうしてこのプロジェクトは生まれ、私たちはここにいます。純粋なBSD makeで書かれ、いかなるバイナリも呼び出さない、完全なマンデルブロ集合レンダラーです。
マンデルブロ集合、レンダリングに36時間18分。1000x500 z=2, it=64, re=-1.4 im=0
このプログラムの使い方:
このリポジトリをクローンしてください: git clone https://github.com/b-aaz/bmake-extravaganza
cd bmake-extravaganza
定義済みのデフォルトに基づいた低解像度画像をレンダリングするには:
make > output.ppm
出力された画像は、PPM形式をサポートする画像ビューアで表示できます。
ffmpegの内部ffplayビューアを使用:
ffplay output.ppm
または、出力をPNGのようなより一般的な形式に変換できます:
ffmpeg -i output.ppm output.png
異なる変数でレンダリングするには:
(これはズームレベル1で200x100の画像をレンダリングします)
make w=200 h=100 z=1 > output.ppm
注意!これは非常に非効率的なレンダラーです。中程度の解像度の画像をレンダリングするだけでも、入力変数とシステム仕様に基づいて、CPU使用率100%で、継続的に1週間かかる可能性があります。
ヒント: 「短い」計算定数をもたらす入力変数を使用してみてください。定数に多くの桁(小数部または十進数)(周期数など)が含まれる場合、加算器、減算器、乗算器などのすべての関数が余分に動作する必要があります。したがって、「短い」定数を持つ高解像度画像は、「長い」/「周期的な」定数を持つ低解像度画像よりも「逆説的に」レンダリングに時間がかかる場合があります。
利用可能なフラグの詳細については、以下を参照してください: make help
想定される質問と回答:
1. ストライプは何ですか?
それは幸運な事故です。修正しようとはしていません。それが作るユニークなパターンが好きです。おそらく、不正確な「浮動小数点」実装の多くのエッジケースの1つによるものです。
マンデルブロ集合、レンダリングに14時間。1000x500 z=2, it=10, re=-1.4 im=0
2. どうやって編集するのですか?
VimにはBSD makeの適切なシンタックスハイライトがなかったため、自分で書く必要がありました。このプロジェクトに非常に役立ちました: bmake.vim
3. 全体の仕組みのTL;DRは?
要するに、加算、減算、乗算の3つの基本的な操作はすべて、単純な十進数の小学校のアルゴリズム(長い加算、単純な桁上げ加算/減算)に基づいて実装されています。これらは単純なルックアップテーブルを使用し、入力数値の桁に繰り返し適用します。
一方、除算は、まずニュートン・ラフソン法で分母の逆数を求め、次に分子にそれを掛けることによって行われます。(「高速除算」と呼ばれることもあります)
他のすべては、これらのプリミティブ(とループ「関数」)の上に構築されています。
このプロセス中にパフォーマンスに注意が払われましたが、改善の余地はまだたくさんあると思います。
3.1. なぜ2の補数(または10の補数)を使わないのですか?
これらの特殊な状況では、多くの一般的なパターンが同じ結果をもたらしません。すべての数値の桁を繰り返し処理する必要がある繰り返し反転の累積コストと、オーバーフローメカニズムに依存する必要があるコスト(これは各数値でさらに多くの反復を必要とするでしょう)は、すべてを遅くするでしょう。
3.2. なぜ一部の領域にコメントがないのですか?
これらのファイルをすべての操作で繰り返し.includeしているため、空行1つ1つが重要です。そのため、パフォーマンスを向上させるために、非常に重要なコードセクションではコメントを削除する必要がありました。
4. BSD-makeで書かれた他のものへの計画は?
それは読者に委ねられた演習です。クレイジーなアイデアは、これに触発されて、バイナリ算術、あるいは単純なISAを実装することです。可能性は無限です。