我正在将C#的DLL编码为高性能模块,所以我使用C++ / CLI,因为在C#中很容易引用它并支持本机代码。
我在msdn上发现,使用#pragmamanaged(push,off)和#pragmamanaged(pop)可以使其中的代码编译为本机代码。
但是根据我的简单测试,结果显示出相反的结果。

这是使用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()的两倍。
但是,如果将loop()放入不同的.cpp文件中,并使用/ clr设置此单个文件,并且不使用#pragmamanaged(push,off)进行任何操作,结果将达到预期的效果。

那么,此#pragma有什么问题?

最佳答案

我自己找到答案,所以我正在回答。

问题是由函数pow()引起的。

pow()所在的math.h仅包含而没有任何预处理程序指令,这意味着它只是按托管方式进行编译。
因此,非托管loop()将必须调用托管pow(),从而从托管main()变为非托管loop(),再到托管pow()的三级跳,并导致开销。
解决方案是用#pragmamanaged(push,off)和#pragmamanaged(pop)包含math.h。

08-26 19:59