ダウンロード ソースコードのダウンロード (53.8 KB)
インデックスメモリアドレッシング
ここまでは少量のデータへのアクセスを見てきましたが、インデックス化されたデータ(配列)ではメモリ割り当てとアクセスのモデルがどのように働くのでしょうか。その点を調べるために、多数の要素からなる配列を単純に反復処理して、各要素へのアクセスに要する時間を比較します。ここでのアクセスとは、データを読み取り、それを変数に格納し、それから再び配列に書き込むことを意味します。
実際に測定に使用する関数は、Javaでは次のようになります。
private void javaTraverse()
{
int temp = 0;
for( int i = 0; i < N_ELEMS; i++ )
{
temp = array[i];
array[i] = temp;
}
}
上記のコード(ArraysAccess.java内)を実行すると、次の結果が返されます。
Java traverse took 53
つまり、1千万個の要素からなる配列を反復処理するのに平均で53ミリ秒を要したことになります。これと同等のC++コードの実装(ダウンロードファイル内のArraysAccessプロジェクトに入っています)は、前の例とは少し異なります。なぜなら、C++ではデフォルトで1つの配列に要素を65,535個までしか入れられないからです。この制限に対処するため、この例でもWindows APIを使用し、GlobalAlloc関数を組み込んでいます。これにより、大きなメモリの割り当てが可能になります。
int main(int argc, char* argv[])
{
int * randoms;
HGLOBAL h = GlobalAlloc( GPTR, sizeof(int) * N_GENERATED );
randoms = (int *)h;
generate_randoms( randoms );
CStopWatch watch;
long double timeNative[N_ITERATIONS];
for( int i = 0; i < N_ITERATIONS; i++ )
{
watch.Start();
nativeTraverse(randoms);
watch.Stop();
timeNative[i] = watch.GetDuration();
}
printf( "C traversing took %lf\n", test_times(timeNative) );
GlobalFree( h );
return 0;
}
ご覧のように、GlobalAllocを使って1千万個のintを割り当ててから、これをJavaのときと同じやり方で反復処理しています。この演算の結果の平均は次のようになります。
C traversing took 10.857639
つまり、Javaより約5倍速いということです。ただし、このコードをコンパイルするときに最適化を無効にすると、Javaより2倍から3倍ほど遅くなります。
この記事は参考になりましたか?
- japan.internet.com翻訳記事連載記事一覧
- この記事の著者
-
japan.internet.com(ジャパンインターネットコム)
japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.com や EarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
Liviu Tudor(Liviu Tudor)
英国在住のJavaコンサルタント。特にオンラインメディアセクタの高可用性システムに関して豊富な経験を持つ。Javaに長年取り組んでいるうちに、パフォーマンスが問題になるアプリケーションをうまく機能させるために必要なのは肥大したミドルウェアフレームワークではなく「低レベル」のコアJavaであると悟る。...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
