[ Home | Programming Tips | Mail ]

Faster Disk I/O


Disk I/Oを高速に行うには

 現在の MacOS(System7.x)は I/O Systemの設計が古いため Diskへの I/Oを高効率で動作させるのは難しいですが、それでもちょっとした工夫で驚くほど高速になります。

 C Standard Libraryの getchar()等は unixでも Macでも Buffering付きの I/O Libraryですので、出来が良ければ File Managerを直接使うよりずっと高速です。(Buffer Sizeは大きめに設定した方が良いでしょう。)これが満足できる速度なら問題はありませんが、さらに速度を求めると File Manager Callを直接使うことになります。

 FSRead()等の File Manager callは unixで言えば read() System Callに相 当する物ですので、C Standard Libraryの様に小さな or Alignしていない I/O単位で呼び出すと効率が極端に悪いです。
 I/Oは programmingの巧拙でものすごい速度差が生じます。以下は 10000個以上の C++ objectを flat化(serialize)して 850K byteの fileに saveする時間を測定した物です。(PowerMac8100/80 + System7.6 + 安物 HDD Quantum capella)


   BufferSize(Kbyte)   DiskCache    Time(msec)
          0              use          27225
          0             bypass        27103
          1              use           2319
          1             bypass         3052
          4              use           1832
          4             bypass         1408
          8              use           1732
          8             bypass          863
         16              use           1410
         16             bypass          654
 BufferSizeは PBWrite()で1回に書き込む単位で、0K byteでは write要求がある度に書き込みますが、16K byteでは write要求が 16K byte溜まってからまとめて書き込みます。

 DiskCacheは File Managerの Cacheを使うかどうかで、同じ場所を1回しか Read / Writeしないのなら Cacheを bypassした方が高速です。(TechNote "FL16-File Mgr Perf & Caching"参照)

 同じ fileを書き込む処理ですが、一番遅い場合(27秒)と速い場合(0.65秒)の差は 40倍以上あります。小さな I/O単位で直接 FSWrite()を使う Programは一番遅い場合に相当しますので、最適化で数10倍速になる可能性があることを示しています。

 高速 Disk I/Oのために以下は必須だと思います。

  1. File Managerへの Read / Write要求は Bufferingして 8K byte以上 4 * n K byte単位で行う。
  2. File Managerの Cacheは Bypassする。

 さらに速くしたい場合は Asynchronous I/O callで I/Oと serialize等の計算処理を並行して行う様にします。ただし PowerPCは高速ですので計算処理が Data圧縮のように非常に重く無い限りそれ程速くはなりません。
 QuickTime / StuffIt等は重い計算処理と I/Oが最高速で動くことを要求されていますので Asynchronous I/Oを使い Codecと並行動作させています。

 Asynchronous I/Oとの組み合わせで複雑な処理を行おうとするとアルゴリズムの複雑化で Bugの元となりますので、その場合は Multi Thread化 + Blocking I/Oで設計した方が良いでしょう。
 PowerPlantの LThread classには Blocking I/Oを行うための仕組みが用意されていますのでこれを利用するのが簡単な方法です。(PP Advanced Topicsマニュアルの Threads in PowerPlant -- Asynchronous Operationsの項に解説があります)


この Pageは MacOS X + Radio UserLand で作っています。