27

次のテスト プログラムを使用して、boost::multi_array のパフォーマンスをネイティブの動的に割り当てられた配列と比較しようとしています。

#include <windows.h>
#define _SCL_SECURE_NO_WARNINGS
#define BOOST_DISABLE_ASSERTS 
#include <boost/multi_array.hpp>

int main(int argc, char* argv[])
{
    const int X_SIZE = 200;
    const int Y_SIZE = 200;
    const int ITERATIONS = 500;
    unsigned int startTime = 0;
    unsigned int endTime = 0;

    // Create the boost array
    typedef boost::multi_array<double, 2> ImageArrayType;
    ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);

    // Create the native array
    double *nativeMatrix = new double [X_SIZE * Y_SIZE];

    //------------------Measure boost----------------------------------------------
    startTime = ::GetTickCount();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {
            for (int x = 0; x < X_SIZE; ++x)
            {
                boostMatrix[x][y] = 2.345;
            }
        }
    }
    endTime = ::GetTickCount();
    printf("[Boost] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);

    //------------------Measure native-----------------------------------------------
    startTime = ::GetTickCount();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {
            for (int x = 0; x < X_SIZE; ++x)
            {
                nativeMatrix[x + (y * X_SIZE)] = 2.345;
            }
        }
    }
    endTime = ::GetTickCount();
    printf("[Native]Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);

    return 0;
}

次の結果が得られます。

[Boost] Elapsed time: 12.500 seconds
[Native]Elapsed time:  0.062 seconds

multi_arrays がそれほど遅いとは信じられません。誰かが私が間違っていることを見つけることができますか?

メモリへの書き込みを行っているため、キャッシュは問題ではないと思います。

編集: これはデバッグ ビルドでした。Laserallanの提案に従って、リリースビルドを行いました:

[Boost] Elapsed time:  0.266 seconds
[Native]Elapsed time:  0.016 seconds

はるかに近い。しかし、16 対 1 はまだ高いように思えます。

決定的な答えはありませんが、先に進み、実際のコードにはネイティブ配列をそのまま残します。

それが私のテストの最大の欠陥だったので、Laserallanの答えを受け入れます。

ありがとうございます。

4

16 に答える 16

34

私のマシンで

g++ -O3 -march=native -mtune=native --fast-math -DNDEBUG test.cpp -o test && ./test

私は得る

[Boost] Elapsed time:  0.020 seconds
[Native]Elapsed time:  0.020 seconds

しかしconst int ITERATIONS5000私が得るように変更

[Boost] Elapsed time:  0.240 seconds
[Native]Elapsed time:  0.180 seconds

次にITERATIONSback to 500butX_SIZEY_SIZEset to400を使用すると、はるかに大きな違いが得られます

[Boost] Elapsed time:  0.460 seconds
[Native]Elapsed time:  0.070 seconds

最後に、ケースの内側のループを反転して、[Boost]次のようにします

    for (int x = 0; x < X_SIZE; ++x)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {

と維持しITERATIONSX_SIZEそしてY_SIZE500400そして400私は得る

[Boost] Elapsed time:  0.060 seconds
[Native]Elapsed time:  0.080 seconds

ケースに対しても内側のループを反転すると[Native](したがって、そのケースでは間違った順序になります)、当然のことながら、

[Boost] Elapsed time:  0.070 seconds
[Native]Elapsed time:  0.450 seconds

gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5Ubuntu 10.10で使用しています

結論として:

  • 適切な最適化により、boost::multi_array は期待どおりに機能します
  • データにアクセスする順序は重要です
于 2010-11-19T00:07:42.590 に答える
11

あなたのテストには欠陥があります。

  • DEBUG ビルドでは、boost::MultiArray に必要な最適化パスがありません。(ネイティブ配列よりもはるかに多く)
  • RELEASE ビルドでは、コンパイラは完全に削除できるコードを探し、ほとんどのコードはそのカテゴリに含まれます

おそらく表示されるのは、最適化コンパイラが「ネイティブ配列」ループのほとんどまたはすべてを削除できることを確認した結果です。理論的には boost::MultiArray ループにも同じことが当てはまりますが、MultiArray はおそらくオプティマイザを打ち負かすほど複雑です。

テストベッドにこの小さな変更を加えると、より現実に即した結果が得られます: " " の両方の出現箇所を " = 2.345"に変更*= 2.345し、最適化して再度コンパイルします。これにより、各テストの外側のループが冗長であることをコンパイラが検出できなくなります。

私はそれを実行し、速度比較を 2:1 に近づけました。

于 2009-01-15T15:50:38.123 に答える
8

リリースまたはデバッグをビルドしていますか?

デバッグ モードで実行している場合、テンプレート マジックが適切にインライン化されておらず、関数呼び出しで多くのオーバーヘッドが発生しているため、boost 配列が非常に遅くなる可能性があります。ただし、マルチ配列がどのように実装されているかはわかりませんので、これは完全にオフになっている可能性があります:)

おそらく保存順序にも違いがあるため、画像を列ごとに保存し、行ごとに書き込んでいる可能性があります。これにより、キャッシュの動作が低下し、動作が遅くなる可能性があります。

X ループと Y ループの順序を入れ替えてみて、何か得られるかどうかを確認してください。ここにストレージの順序に関する情報があります: http://www.boost.org/doc/libs/1_37_0/libs/multi_array/doc/user.html

編集:画像処理に2次元配列を使用しているように見えるので、ブースト画像処理ライブラリgilをチェックすることに興味があるかもしれません。

状況に最適な、オーバーヘッドの少ない配列が含まれている場合があります。

于 2009-01-15T14:17:18.543 に答える
4

代わりにBlitz++の使用を検討してください。Blitzを試してみましたが、そのパフォーマンスはCスタイルのアレイと同等です。

以下に追加されたBlitzを使用してコードを確認してください。


#include <windows.h>
#define _SCL_SECURE_NO_WARNINGS
#define BOOST_DISABLE_ASSERTS 
#include <boost/multi_array.hpp>
#include <blitz/array.h>

int main(int argc, char* argv[])
{
    const int X_SIZE = 200;
    const int Y_SIZE = 200;
    const int ITERATIONS = 500;
    unsigned int startTime = 0;
    unsigned int endTime = 0;

    // Create the boost array
    typedef boost::multi_array<double, 2> ImageArrayType;
    ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);


    //------------------Measure boost----------------------------------------------
    startTime = ::GetTickCount();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {
            for (int x = 0; x < X_SIZE; ++x)
            {
                boostMatrix[x][y] = 2.345;
            }
        }
    }
    endTime = ::GetTickCount();
    printf("[Boost] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);

    //------------------Measure blitz-----------------------------------------------
    blitz::Array<double, 2> blitzArray( X_SIZE, Y_SIZE );
    startTime = ::GetTickCount();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {
            for (int x = 0; x < X_SIZE; ++x)
            {
                blitzArray(x,y) = 2.345;
            }
        }
    }
    endTime = ::GetTickCount();
    printf("[Blitz] Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);


    //------------------Measure native-----------------------------------------------
    // Create the native array
    double *nativeMatrix = new double [X_SIZE * Y_SIZE];

    startTime = ::GetTickCount();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {
            for (int x = 0; x < X_SIZE; ++x)
            {
                nativeMatrix[x + (y * X_SIZE)] = 2.345;
            }
        }
    }
    endTime = ::GetTickCount();
    printf("[Native]Elapsed time: %6.3f seconds\n", (endTime - startTime) / 1000.0);



    return 0;
}

デバッグとリリースの結果は次のとおりです。

デバッグ:

Boost  2.093 secs 
Blitz  0.375 secs 
Native 0.078 secs

リリース:

Boost  0.266 secs
Blitz  0.016 secs
Native 0.015 secs

これにはMSVC2008SP1コンパイラを使用しました。

C-stlyeアレイに別れを告げることができますか?= p

于 2009-02-11T21:54:03.180 に答える
4

私は2つのことを疑問に思っています:

1) 境界チェック: アプリケーションに multi_array.hpp を含める前に、BOOST_DISABLE_ASSERTS プリプロセッサ マクロを定義します。これにより、境界チェックがオフになります。これが NDEBUG のときに無効になるかどうかはわかりません。

2) ベース インデックス: MultiArray は、0 以外のベースから配列にインデックスを付けることができます。つまり、multi_array は (各次元で) ベース番号を格納し、より複雑な式を使用してメモリ内の正確な位置を取得します。それ。

そうしないと、マルチアレイが C アレイよりも遅くなる理由がわかりません。

于 2009-02-19T22:30:18.290 に答える
3

同じ質問があったので、この質問を見ていました。より厳しいテストを行うという考えがいくつかありました。

  1. Rodrigobが指摘したように、最初に添付したコードの結果が誤解を招くデータを与えるなど、ループの順序に欠陥があります。
  2. また、定数を使用して設定されているかなり小さいサイズの配列もあります。コンパイラは、実際にはコンパイラが配列のサイズを認識していない場合でも、ループを最適化することがあります。念のため、配列のサイズと反復回数はランタイム入力にする必要があります。

Mac では、次のコードはより意味のある回答を提供するように構成されています。ここには4つのテストがあります。

#define BOOST_DISABLE_ASSERTS
#include "boost/multi_array.hpp"
#include <sys/time.h>
#include <stdint.h>
#include<string>

uint64_t GetTimeMs64()
{
  struct timeval tv;

  gettimeofday( &tv, NULL );

  uint64_t ret = tv.tv_usec;
  /* Convert from micro seconds (10^-6) to milliseconds (10^-3) */
  ret /= 1000;

  /* Adds the seconds (10^0) after converting them to milliseconds (10^-3) */
  ret += ( tv.tv_sec * 1000 );

  return ret;

}


void function1( const int X_SIZE, const int Y_SIZE, const int ITERATIONS )
{

  double nativeMatrix1add[X_SIZE*Y_SIZE];

  for( int x = 0 ; x < X_SIZE ; ++x )
  {
    for( int y = 0 ; y < Y_SIZE ; ++y )
    {
      nativeMatrix1add[y + ( x * Y_SIZE )] = rand();
    }
  }

  // Create the native array
  double* __restrict const nativeMatrix1p = new double[X_SIZE * Y_SIZE];
  uint64_t startTime = GetTimeMs64();
  for( int i = 0 ; i < ITERATIONS ; ++i )
  {
    for( int xy = 0 ; xy < X_SIZE*Y_SIZE ; ++xy )
    {
      nativeMatrix1p[xy] += nativeMatrix1add[xy];
    }
  }
  uint64_t endTime = GetTimeMs64();
  printf( "[Native Pointer]    Elapsed time: %6.3f seconds\n", ( endTime - startTime ) / 1000.0 );

}

void function2( const int X_SIZE, const int Y_SIZE, const int ITERATIONS )
{

  double nativeMatrix1add[X_SIZE*Y_SIZE];

  for( int x = 0 ; x < X_SIZE ; ++x )
  {
    for( int y = 0 ; y < Y_SIZE ; ++y )
    {
      nativeMatrix1add[y + ( x * Y_SIZE )] = rand();
    }
  }

  // Create the native array
  double* __restrict const nativeMatrix1 = new double[X_SIZE * Y_SIZE];
  uint64_t startTime = GetTimeMs64();
  for( int i = 0 ; i < ITERATIONS ; ++i )
  {
    for( int x = 0 ; x < X_SIZE ; ++x )
    {
      for( int y = 0 ; y < Y_SIZE ; ++y )
      {
        nativeMatrix1[y + ( x * Y_SIZE )] += nativeMatrix1add[y + ( x * Y_SIZE )];
      }
    }
  }
  uint64_t endTime = GetTimeMs64();
  printf( "[Native 1D Array]   Elapsed time: %6.3f seconds\n", ( endTime - startTime ) / 1000.0 );

}


void function3( const int X_SIZE, const int Y_SIZE, const int ITERATIONS )
{

  double nativeMatrix2add[X_SIZE][Y_SIZE];

  for( int x = 0 ; x < X_SIZE ; ++x )
  {
    for( int y = 0 ; y < Y_SIZE ; ++y )
    {
      nativeMatrix2add[x][y] = rand();
    }
  }

  // Create the native array
  double nativeMatrix2[X_SIZE][Y_SIZE];
  uint64_t startTime = GetTimeMs64();
  for( int i = 0 ; i < ITERATIONS ; ++i )
  {
    for( int x = 0 ; x < X_SIZE ; ++x )
    {
      for( int y = 0 ; y < Y_SIZE ; ++y )
      {
        nativeMatrix2[x][y] += nativeMatrix2add[x][y];
      }
    }
  }
  uint64_t endTime = GetTimeMs64();
  printf( "[Native 2D Array]   Elapsed time: %6.3f seconds\n", ( endTime - startTime ) / 1000.0 );

}



void function4( const int X_SIZE, const int Y_SIZE, const int ITERATIONS )
{

  boost::multi_array<double, 2> boostMatrix2add( boost::extents[X_SIZE][Y_SIZE] );

  for( int x = 0 ; x < X_SIZE ; ++x )
  {
    for( int y = 0 ; y < Y_SIZE ; ++y )
    {
      boostMatrix2add[x][y] = rand();
    }
  }

  // Create the native array
  boost::multi_array<double, 2> boostMatrix( boost::extents[X_SIZE][Y_SIZE] );
  uint64_t startTime = GetTimeMs64();
  for( int i = 0 ; i < ITERATIONS ; ++i )
  {
    for( int x = 0 ; x < X_SIZE ; ++x )
    {
      for( int y = 0 ; y < Y_SIZE ; ++y )
      {
        boostMatrix[x][y] += boostMatrix2add[x][y];
      }
    }
  }
  uint64_t endTime = GetTimeMs64();
  printf( "[Boost Array]       Elapsed time: %6.3f seconds\n", ( endTime - startTime ) / 1000.0 );

}

int main( int argc, char* argv[] )
{

  srand( time( NULL ) );

  const int X_SIZE = std::stoi( argv[1] );
  const int Y_SIZE = std::stoi( argv[2] );
  const int ITERATIONS = std::stoi( argv[3] );

  function1( X_SIZE, Y_SIZE, ITERATIONS );
  function2( X_SIZE, Y_SIZE, ITERATIONS );
  function3( X_SIZE, Y_SIZE, ITERATIONS );
  function4( X_SIZE, Y_SIZE, ITERATIONS );

  return 0;
}
  1. 整数演算と二重ループで [] を使用した 1 次元配列のみの 1 つ

  2. ポインターのインクリメントを使用した同じ 1 次元配列を持つもの

  3. 多次元 C 配列

  4. ブースト multi_array

コマンドラインから実行し、実行します

./test_array xsize ysize iterations"

そして、これらのアプローチがどのように機能するかについての良いアイデアを得ることができます. これは、次のコンパイラ フラグで得たものです。

g++4.9.2 -O3 -march=native -funroll-loops -mno-avx --fast-math -DNDEBUG  -c -std=c++11


./test_array 51200 1 20000
[Native 1-Loop ]    Elapsed time:  0.537 seconds
[Native 1D Array]   Elapsed time:  2.045 seconds
[Native 2D Array]   Elapsed time:  2.749 seconds
[Boost Array]       Elapsed time:  1.167 seconds

./test_array 25600 2 20000
[Native 1-Loop ]    Elapsed time:  0.531 seconds
[Native 1D Array]   Elapsed time:  1.241 seconds
[Native 2D Array]   Elapsed time:  1.631 seconds
[Boost Array]       Elapsed time:  0.954 seconds

./test_array 12800 4 20000
[Native 1-Loop ]    Elapsed time:  0.536 seconds
[Native 1D Array]   Elapsed time:  1.214 seconds
[Native 2D Array]   Elapsed time:  1.223 seconds
[Boost Array]       Elapsed time:  0.798 seconds

./test_array 6400 8 20000
[Native 1-Loop ]    Elapsed time:  0.540 seconds
[Native 1D Array]   Elapsed time:  0.845 seconds
[Native 2D Array]   Elapsed time:  0.878 seconds
[Boost Array]       Elapsed time:  0.803 seconds

./test_array 3200 16 20000
[Native 1-Loop ]    Elapsed time:  0.537 seconds
[Native 1D Array]   Elapsed time:  0.661 seconds
[Native 2D Array]   Elapsed time:  0.673 seconds
[Boost Array]       Elapsed time:  0.708 seconds

./test_array 1600 32 20000
[Native 1-Loop ]    Elapsed time:  0.532 seconds
[Native 1D Array]   Elapsed time:  0.592 seconds
[Native 2D Array]   Elapsed time:  0.596 seconds
[Boost Array]       Elapsed time:  0.764 seconds

./test_array 800 64 20000
[Native 1-Loop ]    Elapsed time:  0.546 seconds
[Native 1D Array]   Elapsed time:  0.594 seconds
[Native 2D Array]   Elapsed time:  0.606 seconds
[Boost Array]       Elapsed time:  0.764 seconds

./test_array 400 128 20000
[Native 1-Loop ]    Elapsed time:  0.536 seconds
[Native 1D Array]   Elapsed time:  0.560 seconds
[Native 2D Array]   Elapsed time:  0.564 seconds
[Boost Array]       Elapsed time:  0.746 seconds

したがって、boost multi_array のパフォーマンスはかなり良いと言っても過言ではないと思います。シングル ループ評価に勝るものはありませんが、配列の次元によっては、boost::multi_array がダブル ループを持つ標準の c-array に勝る場合があります。

于 2014-12-09T06:31:38.600 に答える
2

マルチアレイも同様に効率的であると期待していました。しかし、gcc を使用する PPC Mac でも同様の結果が得られます。multiarrayref も試したので、両方のバージョンが同じストレージを使用していましたが、違いはありませんでした。コードの一部で multiarray を使用しており、ハンドコーディングに似ていると想定していたので、これは知っておくとよいでしょう。

于 2009-01-15T15:29:42.953 に答える
2

もう 1 つの試みは、ブースト配列の単純なインデックスの代わりにイテレータを使用することです。

于 2009-01-15T14:24:49.277 に答える
1

私は問題が何であるかを知っていると思います...多分。

ブーストの実装に次のような構文を持たせるために: matrix[x][y]. つまり、matrix[x] は 1D 配列columnのように機能するオブジェクトへの参照を返す必要があり、その時点で reference[y] は要素を提供します。

ここでの問題は、行優先順で反復していることです(ネイティブ配列は行優先 IIRC であるため、これは c/c++ では一般的です。この場合、コンパイラは各 y に対して行列 [x] を再実行する必要があります。ブースト マトリックスを使用するときに列の主要な順序を変更すると、パフォーマンスが向上する場合があります。

ただの理論です。

編集: Linux システムで (若干の変更を加えて) 自分の理論をテストし、x と y を切り替えることでパフォーマンスの向上を示しましが、それでもネイティブ配列よりも低速でした。これは、コンパイラが一時参照型を最適化できないという単純な問題である可能性があります。

于 2009-01-15T15:37:14.047 に答える
1

g++ 4.8.2 によって生成されたアセンブリをと の-O3 -DBOOST_DISABLE_ASSERTS両方を使用して要素にアクセスするoperator()[][]、ネイティブ配列や手動のインデックス計算と比較して唯一の余分な操作がベースの追加であることが明らかです。ただし、これのコストは測定しませんでした。

于 2014-06-03T17:01:20.903 に答える
1

を使用してSnow Leopard Mac OSでテストしましたgcc 4.2.1

Debug:
[Boost] Elapsed time:  2.268 seconds
[Native]Elapsed time:  0.076 seconds

Release:
[Boost] Elapsed time:  0.065 seconds
[Native]Elapsed time:  0.020 seconds

コードは次のとおりです (Unix でコンパイルできるように変更されています)。

#define BOOST_DISABLE_ASSERTS
#include <boost/multi_array.hpp>
#include <ctime>

int main(int argc, char* argv[])
{
    const int X_SIZE = 200;
    const int Y_SIZE = 200;
    const int ITERATIONS = 500;
    unsigned int startTime = 0;
    unsigned int endTime = 0;

    // Create the boost array
    typedef boost::multi_array<double, 2> ImageArrayType;
    ImageArrayType boostMatrix(boost::extents[X_SIZE][Y_SIZE]);

    // Create the native array
    double *nativeMatrix = new double [X_SIZE * Y_SIZE];

    //------------------Measure boost----------------------------------------------
    startTime = clock();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {
            for (int x = 0; x < X_SIZE; ++x)
            {
                boostMatrix[x][y] = 2.345;
            }
        }
    }
    endTime = clock();
    printf("[Boost] Elapsed time: %6.3f seconds\n", (endTime - startTime) / (double)CLOCKS_PER_SEC);

    //------------------Measure native-----------------------------------------------
    startTime = clock();
    for (int i = 0; i < ITERATIONS; ++i)
    {
        for (int y = 0; y < Y_SIZE; ++y)
        {
            for (int x = 0; x < X_SIZE; ++x)
            {
                nativeMatrix[x + (y * X_SIZE)] = 2.345;
            }
        }
    }
    endTime = clock();
    printf("[Native]Elapsed time: %6.3f seconds\n", (endTime - startTime) / (double)CLOCKS_PER_SEC);

    return 0;
}
于 2010-08-01T09:13:10.133 に答える
1

同様の質問が尋ねられ、ここで回答されました:

http://www.codeguru.com/forum/archive/index.php/t-300014.html

簡単に言えば、コンパイラが単純な配列を最適化するのが最も簡単で、Boost バージョンを最適化するのはそれほど簡単ではないということです。したがって、特定のコンパイラは、Boost バージョンに同じ最適化の利点をすべて提供しない場合があります。

コンパイラは、最適化の程度と保守的 (テンプレート化されたコードやその他の複雑さなど) の点でも異なります。

于 2009-12-01T15:13:27.963 に答える
1

リリース モードでビルドし、objdump を使用して、アセンブリを確認します。それらはまったく異なることをしている可能性があり、コンパイラがどの最適化を使用しているかを確認できます。

于 2009-01-15T19:17:22.463 に答える
0

上記のコードを Visual Studio 2008 v9.0.21022 で修正し、C および C++ の Numerical Recipe ルーチンからコンテナー ルーチンを適用しました。

http://www.nrbook.com/nr3/ライセンスされたルーチン dmatrix と MatDoub をそれぞれ使用

dmatrix は古い構文 malloc 演算子を使用しており、推奨されません... MatDoub は New コマンドを使用します

秒単位の速度はリリース バージョンです。

ブースト: 0.437

ネイティブ: 0.032

数値レシピ C: 0.031

数値レシピ C++: 0.031

したがって、上記のように、電撃戦は最高の無料の代替手段のように見えます.

于 2010-01-04T13:28:58.517 に答える
0

VC++ 2010 で最適化をオンにして (「速度を最大化」し、「任意の適切な」関数をインライン展開し、「高速コードを優先」して) コードを (わずかに変更して) コンパイルし、0.015/0.391 の時間を取得しました。私はアセンブリ リストを生成しましたが、私はひどいアセンブリ初心者ですが、ブースト測定ループ内に 1 行があり、私にはよく見えません。

call    ??A?$multi_array_ref@N$01@boost@@QAE?AV?$sub_array@N$00@multi_array@detail@1@H@Z ; boost::multi_array_ref<double,2>::operator[]

[] 演算子の 1 つがインライン化されませんでした! 呼び出されたプロシージャは別の呼び出しを行います。今回は次のようにしmulti_array::value_accessor_n<...>::access<...>()ます。

call    ??$access@V?$sub_array@N$00@multi_array@detail@boost@@PAN@?$value_accessor_n@N$01@multi_array@detail@boost@@IBE?AV?$sub_array@N$00@123@U?$type@V?$sub_array@N$00@multi_array@detail@boost@@@3@HPANPBIPBH3@Z ; boost::detail::multi_array::value_accessor_n<double,2>::access<boost::detail::multi_array::sub_array<double,1>,double *>

全体として、2 つのプロシージャは、配列内の 1 つの要素にアクセスするだけの非常に多くのコードです。私の一般的な印象は、ライブラリが非常に複雑で高レベルであるため、Visual Studio では思うように最適化できないということです (gcc を使用したポスターは、明らかにより良い結果を得ています)。

私見、優れたコンパイラは実際に2つの手順をインライン化して最適化する必要があります-どちらもかなり短くて簡単で、ループなどは含まれていません.引数と結果を渡すだけで多くの時間が無駄になる可能性があります.

于 2011-09-13T13:04:11.630 に答える