C ++ / CLI中的#pragma托管(推送,关闭)会影响性能吗?

时间:2013-03-20 08:42:14

标签: interop c++-cli

我正在为C#编写一个DLL作为高性能模块,因此我使用C ++ / CLI,因为它很容易在C#中引用并支持本机代码。 我在msdn上发现使用#pragma managed(push,off)和#pragma managed(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;
}

性能分析表明,非托管循环()的成本是clrloop()的两倍。 但是如果我把loop()放到不同的.cpp文件中并将这个单个文件设置为wihouth / clr,并且没有使用#pragma managed(push,off)的东西,结果就像预期的那样好了。

那么,这个#pragma的问题是什么?

2 个答案:

答案 0 :(得分:6)

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

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

pow()所在的 math.h 只是包含在没有任何预处理器指令的情况下,这意味着它只是被编译为托管。 因此,非托管循环()必须调用托管pow(),从而成为从托管main()到非托管循环()到托管pow()的三跳,并导致开销。 解决方案是使用#pragma managed(push,off)和#pragma managed(pop)包含 math.h

答案 1 :(得分:0)

maverix3的回答:

您应该使用非托管功能并将其放在不使用预编译头文件的单独CPP文件中,以便手动在#pragma managed(push,off)部分中包含所有头文件。 然后添加一个头文件,并记住在函数定义周围添加相同的pragma包装器。