2013年10月20日日曜日

60 fps を実現する超高速イメージキャッシュ

Path謹製のイメージキャッシュライブラリ。イメージ表示にかかる様々なオーバーヘッドを減らすことで 60fpsを実現している。またメモリのフットプリントも従来方式の半分と省メモリ。

先に種を明かすと非圧縮のイメージデータをキャッシュすることでかかるオーバヘッドを減らしている。その特性上サムネイル画像など小さいサイズのイメージが向いている。またオリジナルイメージの保存管理は行わない。
githubのreadmeにはライブラリで使われているテクニックが丁寧に解説されていて非常に参考になる。それ自身が高速化のヒントになるのでライブラリを使わなくても一読をおすすめ。


高速化テクニックのポイントは次の通り。

1. 単一ファイルで複数イメージを管理 (Image Table)
複数イメージを単一ファイルで管理し、さらにファイルは最初の一回オープンした後、mmapでメモリへマップしたままクローズしないで使い続ける。これによって複数ファイル毎のオープン・クローズのオーバヘッドを減らしている。また mmapにより必要な時にディスク→メモリへの読み込みが行われる(遅延処理)。

2. 非圧縮イメージを保存
イメージを表示する時の一番のオーバーヘッドはデコード処理(非圧縮処理)。これを避ける為にオリジナルイメージ(JPEGなど)からデコードした後の非圧縮形式のデータを保存しておき表示する時にはこれをそのまま使う。この特性上通常よりも使用するディスク容量が多くなる。例えば 100x100pixelのサムネイルを 250個キャッシュすると 4bytes/pixel x 100 x 100 x 4 = 10MB消費。掲載されているデモプログラムの比較では通常 568KBに対して2.2MBのディスク使用だった。

3. バイトアライメント(byte-alignment)調整
データが非圧縮であってもイメージを描画するCoreAnimationが扱うバイトアライメントに合致しないとその変換のためにデータコピーが発生してこれがオーバヘッドとなる。このオーバヘッドを無くす為にキャッシュ作成時にあらかじめバイトアライメントをCoreAnimation向けに調整しておく。

デコードやメモリーコピーといったオーバーヘッドを無くして、ディスクから読み出されたデータがそのまま描画される流れを作ることで高速化を実現している。


その他、非同期のAPIを提供、50x50,100x100といったように複数のサムネイルセットを扱えるようになっていたりと実用的。ただAPIの使い方は若干煩雑なので慣れが必要か(でも難しくはない)。


ドキュメント最後には従来方式との比較デモがビデオ付きで掲載されている。それぞれの各種値の比較表

非圧縮なのでディスク容量は増えてしまうがフレームレートは約2倍出ていて劇的に速くなっている。
フットプリント(RPRVT = amount of resident memory consumed by our heap allocations)が半分になっているのも特徴的。デコードやメモリコピーを避けたことによってその分消費メモリも激減している。


- - -
いいなーこれ。
久々に面白いテクニックが見られてワクワクした。

0 件のコメント:

コメントを投稿