4

I need to pass data from C++ to C# frequently. It should be as fast as possible as i'm writing ultra low latency trading application.

I have pure C++ project (will be ported to Linux later). I need to pass data from it to my C# project. I always need to pass the same structure (if this is important).

Structure looks like that: Ticker = "MSFT" Price = "30" Volume = "10" Side = "Buy"

I imagine two options:

  • write C++-CLI wrapper which will pass UnmanagedMemoryStream from C++ to C#
  • use memory-mapped files

What would be:

  • faster
  • easier to implement
  • easier to port to Linux ?
Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305
  • 1
    The C++ and C# code end up in two separate processes, or in the same process? I.e. do you need to transfer data between different processes or through the managed/unmanaged boundary within the same process? 'Porting to Linux' = using Mono for the C# part? – MiMo Feb 16 '13 at 20:42
  • Yes that's quite an important point. I was assuming separate processes. – Matthew Watson Feb 16 '13 at 20:46
  • it's the same project and yes I assume it could be the same process. Porting to Linux is most likely rewriting the rest of of C# code to C++. However Mono is also possible... And having my current library as "standalone" application could be cool (if not affect latency significantly). It would be cool to share `Ticker = "MSFT" Price = "30" Volume = "10" Side = "Buy"` between several other processes. So requirements are vague but latency is surely the most important part! However I agree to loose 1-10 microseconds for having some cool features like sharing data to several other processes. – Oleg Vazhnev Feb 16 '13 at 20:54
  • i'm not Linux expert but it seems `mmap` is something in Linux that very fast. So I probably need to use someting like that in Windows so i can port it later easily.... – Oleg Vazhnev Feb 16 '13 at 21:12

2 Answers2

2

Using mixed-mode C++/CLI assemblies is not supported on Mono at all (see here). Mono only supports pure CLR C++ assemblies.
Consequently, it seems that other possibilities, such as memory mapped files, or as Matthew suggested using P/Invoke (which is supported on Mono, though it requires some extra work) is what you should use if you plan to port to Linux.

JKor
  • 3,822
  • 3
  • 28
  • 36
1

Memory-Mapped files are both very fast and relatively easy to use. I have used them to transfer large amounts of ECG data from a C# application to a C++ application. I have also used them to transfer smaller blocks of memory (such as a struct). It's about as fast as you can possibly get for interprocess data transfer. (You'll probably need to use a synchronisation mechanism such as a semaphore to control reading/writing of the data from each end.)

However, I don't know if they are easy to port to Linux - but I do know that Linux supports some kind of MMF so I'm betting it won't be too hard. But I can't say for sure.

NOTE: If you want to transfer data to a C++ function in a DLL that is running in-proc, that's a completely different matter, and you can just use P/Invoke to do that. Using P/Invoke will be much faster than using an MMF (assuming that the data can be pinned by the marshaller and won't need to be copied). Generally speaking, with P/Invoke you can end up just passing a pointer to the C++ function.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • to the best of my knowledge P/Invoke is comparatively SLOW. C++-CLI call should be faster! – Oleg Vazhnev Feb 16 '13 at 21:14
  • No, P/Invoke is not slow if the marshaller doesn't have to copy the memory. It only has to pass a pointer to the unmanaged DLL (after pinning the block of memory that it's passing). Compared to copying the block of memory using the MMF functions, that's going to be a lot faster. – Matthew Watson Feb 16 '13 at 23:28
  • "In other words, C++ Interop uses the fastest possible method of data marshaling, whereas P/Invoke uses the most robust method. This means that C++ Interop (in a fashion typical for C++) provides optimal performance by default, and the programmer is responsible for addressing cases where this behavior is not safe or appropriate." from here: http://msdn.microsoft.com/en-us/library/ky8kkddw(v=vs.80).aspx – Oleg Vazhnev Feb 20 '13 at 17:19