3
votes

I'm coding a DLL for C# as a high-performance-module so I use C++/CLI because it's easy to referred in C# and supports native code. I found on msdn that using #pragma managed(push, off) and #pragma managed(pop) could make codes in it compiled as native code. But according to my simple test, the result was showing contrary.

Here's the code, compiled with /clr using Visual Studio 2012.

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;
}

Performance analysis showed that the unmanaged loop() cost twice to clrloop(). But if I put the loop() into different .cpp file and set this single file compiled wihouth /clr, and without any use of #pragma managed(push, off) things, the result was good as expected.

So, what's the problem with this #pragma?

2
Actually all my tests were using Release build without any manual change on solution or project's properties. And this loop() never went away. (I noticed it went away on pure native C++ if I made it return void.) I hope some one could reproduce this on his machine (better same vs2012) and see if it make any difference then it will make me easier to see if it's my configures fault.maverix3
I find the reason why. The issue is the function pow(). The math.h which the pow() is in, is simply included without any preprocessor directive, it means that it's simply compiled as managed. So the unmanaged loop() will have to call a managed pow(), thus become a tri-jump from managed main(), to unmanaged loop(), to managed pow(), and causes overheads. The solution is to encompass the math.h with #pragma managed(push, off) and #pragma managed(pop).maverix3
Go ahead and make that an answer (when the site allows it)Ben Voigt

2 Answers

6
votes

I find the answer by myself, so, I'm answering it.

The problem is caused by the function pow().

The math.h which the pow() is in, is simply included without any preprocessor directive, it means that it's simply compiled as managed. So the unmanaged loop() will have to call a managed pow(), thus become a tri-jump from managed main(), to unmanaged loop(), to managed pow(), and causes overheads. The solution is to encompass the math.h with #pragma managed(push, off) and #pragma managed(pop).

0
votes

An addition to maverix3's answer:

You should take your unmanaged function and place it in a separate CPP file that does NOT use precompiled headers so you manually include all of your header files within the #pragma managed(push,off) section. Then add a header file and remember to add the same pragma wrapper around the function definition.