3

C#用のDLLを高機能モジュールとしてコーディングしているので、C#で参照しやすくネイティブコードにも対応していることからC++/CLIを使用しています。#pragma managed(push, off) と #pragma managed(pop) を使用すると、コードをネイティブ コードとしてコンパイルできることがmsdnでわかりました。しかし、私の簡単なテストによると、結果は逆でした。

Visual Studio 2012 を使用して /clr でコンパイルされたコードを次に示します。

int clrloop()
{
  for (int i = 0; i < 999999999; i++)
  {
      double test=9.999;
      test=pow(test, 10);
  }
  return 0;
}

#pragma managed(push,off)
int loop()
{
  for (int i = 0; i < 999999999; i++)
  {
      double test=9.999;
      test=pow(test, 10);
  }
  return 0;
}
#pragma managed(pop)

int main(array<System::String ^> ^args)
{
    int a=loop();
    int b=clrloop();
    return 0;
}

パフォーマンス分析では、管理されていない loop() が clrloop() に対して 2 倍のコストを要したことが示されました。しかし、loop() を別の .cpp ファイルに入れて、この単一のファイルを /clr でコンパイルし、#pragma managed(push, off) を使用せずに設定すると、期待どおりの結果が得られました。

では、この #pragma の何が問題なのでしょうか?

4

2 に答える 2

6

答えは自分で見つけたので、答えています。

この問題は関数 pow() によって引き起こされます。

pow() が含まれているmath.hは、プリプロセッサ ディレクティブなしで単純に含まれています。これは、マネージとしてコンパイルされていることを意味します。そのため、アンマネージド loop() はマネージド pow() を呼び出す必要があり、マネージド main() からアンマネージド loop()、マネージド pow() へのトライジャンプになり、オーバーヘッドが発生します。解決策は、 math.hを #pragma managed(push, off) および #pragma managed(pop) で囲むことです。

于 2013-03-22T08:41:58.803 に答える