Tutorial :Optimize managed to native calls



Question:

What can be done to speed up calling native methods from managed code?

I'm writing a program which needs to be able to manage arbitrarily-sized lists of objects and retrieve information from them at high speed, which it feeds into scripts. Scripts are bits of compiled C# code. I'm writing a basic interface layer from the C++ (native) DLL/SO/etc to the C# (.Net or Mono) management layer.

Now, I've been doing some testing, and I've found that on average, PInvoking a native method from managed code is something like 100 times slower than doing it all in managed (all native and all managed are identically fast, for reference).

The syntax I was using is:

[DllImport("test.dll")]  extern static public String test_method(String value);    String returnedValue = test_method("hello world");  

Is there a way to cache a pointer to the function, some code of fast invoker, that would increase speed after loading the native library? That would solve the problem quite neatly, so I doubt it exists. :P

Edit: I didn't specify, but this needs to work on Windows, Linux (Ubuntu at least) and Mac OS X, all for both x86 and x64. Otherwise I would've gone with a C++/CLI interface and been done with it, but unless that works for all 3 platforms, I can't use it.


Solution:1

Further to my question comment, we've established that it was a debug build with the debugger attached. This has a massive impact on runtime performance of .Net code. Easy mistake to make. :)

I'm guessing with a release build and no debugger attached, the performance difference is now much more reasonable.

If you have a very chatty API, and the native methods being called are cheap, then method call overhead can be a performance issue. Try and design a less chatty API. This is a typical technique used to increase the performance of boundary\systems communications.

If performance is acceptable after sorting the debugger issue, there is a simple technique that I have used to easily get a substantial performance increase in chatty APIs, by just adding a single attribute.

In the classes where you have your imported functions (i.e. the DllImport functions), place the SuppressUnmanagedCodeSecurity attribute on the classes. This will remove some expensive security checking from each P/Invoke call. Please see the documentation on SuppressUnmanagedCodeSecurity to understand the ramifications of this. I tend to keep my imported functions grouped together in internal classes (that only contain imported functions) with this attribute applied.


Solution:2

Perhaps the string marshalling is what is causing a slowdown. For comparison sake, try to profile a function that takes and returns elementary C++ types like int.

You can also try to experiment with C++/CLI. That way you can take explicit control over the marshalling and maybe see an improvement.

In C++/CLI assembly:

System::String ^ test_method(System::String ^ args)  {      pin_ptr<const wchar_t> pp = PtrToStringChars(args);      //This might leak, probably needs a smart pointer to wrap it      wchar_t* ret = native_method(pp);      return gcnew String^(ret);  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »