この特集のトップページへ

Visual C++によるアプリケーション

 C言語やC++で開発されたアプリケーションの性能を改善するには,ハードウェアアーキテクチャの理解が非常に重要となる。ハードウェアアーキテクチャを理解したうえでデータキャッシュを効率的に活用できるようにデータ宣言やループ処理を実装しなければ,性能を最適化することは難しい。PCサーバーに利用されているプロセッサがIntel社製であれば,Webから最適化マニュアルをダウンロードすることができる*1

○アプリケーションが使用するメモリ領域を静的に確保する
 メモリの使用効率の観点からすると,必要になったときにメモリを確保し,不要になったら直ちにメモリを解放することが望ましい。しかし,メモリの確保と解放を頻繁にくり返せば,そのオーバーヘッドは無視できないものとなり得る。
 また,くり返しアクセスするデータを動的なメモリ領域に割り当てると,メモリを確保するたびにディスクへのアクセスが発生し,性能に影響を与えることがある。特にrealloc関数の利用は避けるべきである。

○32バイト以上のデータ構造体や配列を利用する場合は32バイト境界に合わせる
 Intel社製のPentiumプロセッサには,境界にまたがるアクセスを実行すると余分なクロックサイクルを消費するという特性がある。つまり,それだけ性能が劣化してしまう。したがって,32ビットのデータは4バイトの境界に,64ビットのデータは8バイトの境界に,80ビットのデータは16バイトの境界に合わせることが望ましい。32バイト以上のデータ構造体や配列は,各構造体または配列要素の先頭を32バイトの境界に合わせ,構成要素が32バイトのキャッシュライン境界をまたがないようにすることで,余分なクロックサイクルの消費を抑えることができる。

 また,構造体の構成要素は大きい要素から順に宣言し,アクセス頻度の多いデータ要素をまとめて配置するといった工夫も必要である。

○ループ処理において,ループフュージョン(Loop Fusion)やループフィッション(Loop Fission)を適切に使い分ける
 ループフュージョンは同じデータにアクセスする2つのループを結合して,データがキャッシュ上に存在するあいだに多くの処理を実行させようとする方法である。
 これに対してループフィッションは,キャッシュされたデータの処理が完了するまえに1つのループに含まれる2つのループがキャッシュからフラッシュされないように,ループを分割して性能低下を避ける方法である。

・ループフュージョン

 次のリストのうち,List 9-1がループフュージョン前で,List 9-2がループフュージョン後である。同じデータcus_balにアクセスするループが2つあり,キャッシュに余裕があれば,それを1つのループにすることで,データがキャッシュ上で処理できる可能性が高まる。

・ループフィッション

 次のリストのうち,List 9-3がループフィッション前であり,List 9-4がループフィッション後である。この場合は異なるデータcus_balとtot_balのループ処理が1つのループに含まれているが,両方の配列をキャッシュに格納できない場合は,ループ処理が完了するまえに未処理のデータがキャッシュからフラッシュされる可能性を抑えるため,2つのループに分ける。

○UnicodeとANSIのデータ変換を避ける
 データのコード変換はオーバーヘッドが大きい。特にUnicodeとANSIのデータ変換には相当なオーバーヘッドがかかるので,できるだけ必要最小限に抑える。

○_tryステートメント,_finallyステートメント,_catchステートメントの使用を避ける
 これらのステートメントは,Microsoft社が独自にC言語およびC++に拡張を加えた機能であり,例外発生時にメモリを解放したり,ファイルをクローズしたり,ファイルハンドルを解放したりするときに使用する。もしこれらのステートメントを使用して例外処理を実装したいのであれば,「新しいC++例外処理メカニズム*2」を使用する。

○コンパイル時に[実行速度を優先]オプションを指定する
 Visual C++でコンパイルするときに/Otオプションを指定すると,コードサイズの最小化よりも実行速度の最適化を優先するようになる。あるいは,プロジェクトプロパティで[最大限の最適化]オプションを選択しても,実行速度を高速化するために各種の最適化処理が実行される。

○Intel社製のコンパイラを使用する
 Windows NT上で動作するアプリケーションをC++で開発する場合,一般的にはVisual C++を利用して開発するだろう。あらゆる性能解決策を試みてもVisual C++で開発したアプリケーションの性能が目標値を達成しない場合は,Visual C++以外のコンパイラを試してみるのも1つの方法である。特にハードウェアベンダーが販売しているコンパイラは,利用してみる価値がある。Intel社製のプロセッサを使用したPCサーバーやPCクライアント上で稼働させるアプリケーションであれば,Intel社が販売しているC++コンパイラ*3を使用して,性能が改善されるか否かを確かめてみるとよいだろう。


  1. 下記のアドレスを参照してほしい。
    ○Pentium V
    http://www.intel.co.jp/jp/developer/design/pentiumiii/manuals/index.htm
    ○Pentium U
    http://www.intel.co.jp/jp/developer/design/pentiumii/manuals/index.htm

  2. ISO WG21/ANSI X3J16の作業文書に基づきC++に組み込まれている例外処理メカニズムのこと。C++では,C言語の例外処理(Win32の構造化例外処理メカニズム)を扱うことができるため,C++専用の例外処理メカニズムということで,Microsoft社のマニュアルでは「新しいC++例外処理メカニズム」と表現されている。
  3. Intel社製のC/C++コンパイラは,Win32アプリケーションを開発するために設計されたVisual C++ IDE(Integrated Development Environment)用のプラグインコンパイラである。p.832で紹介したVtuneのCD-ROMに収録されている。
前へ Chapter 9 19/46 次へ