我正在为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的问题是什么?
答案 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包装器。