tags:

views:

2225

answers:

10

Hello everyone... I'm looking into developing an application that will process data from a line-scan camera at around 2000 lines (frames) per second. For this real-time application, I feel that C/C++ are the way to go. (It is my feeling, and others will agree that Managed code just isn't right for this task.)

However, I've done very little MFC, or any other C++ GUI. I am really getting to do C# GUIs very well, though.

So it seems natural to me to write the data-intensive code in C/C++, and the GUI in C#. The GUI will be used for set-up/calibration/on-line monitoring (and possibly outputting of data via UDP, because it's easier in C#.

So first, I'd like to see if anyone agrees that this would be the way to go. Based on my programming experience (good at low-level C algorithms, and high-level C# GUI design), it just feels right.

Secondly, I'm not sure the right way to go about it. I just threw together a solution in VS2005, which calls some (extern "C") DLL functions from a C# app. And to make sure I could do it, I wrote to some global variables in the DLL, and read from them:

/** test.h **/
int globaldata;
extern "C" __declspec(dllexport) void set(int);
extern "C" __declspec(dllexport) int  get();

/** test.cpp **/
extern int data=0;
__declspec(dllexport) void set(int num) {
    data = num;
}

__declspec(dllexport) int get() {
    return data;
}

/** test.cs **/
[DllImport("test")]
private static extern void set(int num);

[DllImport("test")]
private static extern int get();

Calling get() and then set() work properly (get returns the number that I passed to set()).

Now, I know that you can export a C++ class as well, but does it have to be managed? How does that work? Am I going about this the right way?

Thanks for all your help!

*** EDIT ***

First of all, THANK YOU for your fantastic answers so far! I'm always incredibly impressed with StackOverFlow...

I guess one thing I should have hit on more, was not necessarily raw speed (this can be prototyped and benchmarked). One thing that has me more concerned is the non-deterministic behavior of the Garbage Collector. This application would not be tolerant of a 500ms delay while performing garbage collection.

I am all for coding and trying this in pure C#, but if I know ahead of time that the GC and any other non-deterministic .NET behavior (?) will cause a problem, I think my time would be better spent coding it in C/C++ and figuring out the best C# interface.

+17  A: 

There is no reason that you can't write high performance code entirely in C#.

SO questions on the same/similiar topic:

Other articles:

Mitch Wheat
That's one of C# biggest advantages over Java...**pointers**.
Lucas McCoy
As far as I am aware .NET *still* doesn't support SIMD instructions. Mono does but that's little different story.So yes on some tasks C++ esspecially compiled with ICC will be significally faster.
Ray
@Ray: strictly speaking the question wasn't about whether .NET doesn't support SIMD instructions....
Mitch Wheat
It actually was Mitch: "... I'm looking into developing an application that will process data from a line-scan camera at around 2000 lines (frames) per second."
Ray
@Ray: so use multiple threads.
Mitch Wheat
Thread usage will not compensate lack of SIMD support.
Ray
True on both counts. .NET code is not necessarily slower than naive code, as Mitch's links show. In many cases, managed code turns out faster than native, even. ( http://blogs.msdn.com/ricom/archive/2005/05/10/performance-quiz-6-chinese-english-dictionary-reader.aspx is a particularly enlightening read), but true, if you're able to take advantage of SIMD, native code gains a significant advantage. But in the general case, it is a bad idea to assume that "I need performance, so I'd probably better write in C/C++". Those languages do not magically make your code go faster.
jalf
.Net CLR uses SIMD instructions for some internal operations (memory operations, some math operations etc.) so you do get some SIMD with .Net, but currently it doesn't use SIMD when compiling CIL to native code.
Pop Catalin
A: 

The language you'll choose will not affect much the performance (say you can affect speed by 5/10%). What will make the difference is the algorithms you will be using, how you process data, profiling your application, etc... (performance could change with a ratio of 10x).

Nicolas Viennot
+1  A: 

I agree with Mitch 100%.

If after investigating his resources, you still feel that you need to use some unmanaged code, you can write a "business" layer in C++ (or in this case, really a functional layer) and write your UI in C#. Use COM Interop to call from C#/managed code to your unmanaged code.

Again, though, my feeling is that you will not need to do this.

Eric J.
+2  A: 

For C++ you use C++/CLI - which is actually not that bad. It's a lot better than the old managed extensions.

To comment on performance. It really depends. How much back and forth will the there be between your C++ code and your C# code? Will you have a background thread gathering data in C++ and periodically sending that to the C# code? If you are going to be interfacing with a device, will it be using serial, USB, some API you have been given?

sylvanaar
Yes, you've got it. The background thread will be gathering data from the frame buffer on the camera, and re-assembling the image, and making calculations. Then periodically the C# will poll (or the C++ will callback?) to provide some data, and the C# app will send this out via UDP socket.The interface depends on the hardware we select, but the one I've been looking at was USB 2.0, and they provided the C++ API.Is C++/CLI managed? Again, I'm worried about the non-deterministic GC causing sporadic delays as I manipulate a large amount of data.
Jonathon Reinhart
Performance also depends on other factors - for example, the C++/CLI implementation of STL is dreadfully slow, so much so the .NET containers outperform it.
gbjbaanb
+4  A: 

The first thing you need to do is test your assumption. What are your performance constraints? What sort of hardware are you expecting to host the application? Write a small program in C# that deals with the core problem and measure how fast it runs.

Only once you have the facts can you make a decision about whether or not to use C/C++ over a managed solution.

Along with others who have commented, I suspect that a C#/managed solution will do just fine, especially if you make use of the .NET Parallel Extensions.

If you end up going the C/C++ route, then there are two options re interop, namely, pInvoke and COM interop. I don't believe there's a clean way to access unmanaged C++ classes directly from .NET; to this end, you would have to consider implementing a managed/unmanaged C++ assembly.

Eric Smith
C++ solutions can use OpenMP (parallel extensions) just about as easy
Ray
And C# apps can use Parallel extensions, or .net4, which is not too far from OpenMP
erikkallen
gbjbaanb
+5  A: 

For real time application: I recommend C++, you will be more flexible with memory management, faster, and even multi-platform depending on what framework is used...!

About framework and GUI, I recommend you having a look at Qt. Qt is a great framework for C++ software development.

I guess it's the solution to your problem !

Matthieu
+9  A: 

In my opinion your solution is a sound one:

  1. Even though C# is fast it never can compete with a well written unmanaged C/C++, I have made high-performance applications myself that proves this beyond the tiny examples that people always post when someone posts these kinds of statements
  2. MFC or ATL UI programming is cumbersome and slow, C# is the way to go here, I NEVER will do MFC/ATL UI programming ever again, unless forced to

Your solution, in case you haven't figured it out yet, is called "Mixed Mode", which basically means that you combine Managed (C#) and Unmanaged (C/C++) code in the same projects, it is often a bit of a hassle to get the VS project up-and-running (LNK2020 errors..argh..) but when you find the right settings it should work just fine.

Only negative thing is that mixed mode assemblies must run in Full Trust, if that's OK then I guess you know what to do.

One other thing you might want to look at is an open source project called SWIG. SWIG takes your C/C++ code and creates a .NET assembly out of it, I have used it myself in my TM++ open source project. See here for more information about SWIG http://www.swig.org/.

Inge Henriksen
I've seen a few people mention SWIG before... one thing I'm concerned with is the development process... I'm planning on kind of writing both the GUI and the main app at the same time (the GUI allowing me to see what's going on in the main app).With SWIG, it seems that I could continually have to re-SWIG it before I could do anything with it from the C# GUI. Is this the case?I would think VS should be able to handle something like this with ease, no?
Jonathon Reinhart
Usually you dont have to change the SWIG interface definition file, you only need to add your C/C++ header-files to it, and in some cases you must do advanced stuff, but in most cases SWIG will scan your headers. Here is an example of a SWIG interface definiton file:http://tmplusplus.svn.sourceforge.net/viewvc/tmplusplus/trunk/src/TMPlusPlus.i?revision=350
Inge Henriksen
..and to make your .NET assembly you can do something like this:swig -c++ -csharp -outdir ./SWIG -lcpointer.i TMPlusPlus.iwhere TMPlusPlus.i is the SWIG interface definition file above.
Inge Henriksen
For the "Mixed Mode" method, I'm assuming I have one VS2005 Solution, with two projects in it, one being the C# GUI. What is the other? Is it C++ CLR? And once I write my (unmanaged) C++ class, can I still instantiate it in the C# and start a new thread on it? Or would I call a static function in the C++ from the C#, which would in tern instantiate itself...
Jonathon Reinhart
Hi, Jonathon. Yes, exactly, your solution has two clr projects (C++ and C#), and one unmanaged C/C++ project. From the Managed C++ project you can add your other C/C++ libraries (*.lib) as Additional Dependencies under Project Property Settings->Configuration Properties->Linker->Input in VS 2005. Your managed C++ project would work as a interface or wrapper for you unmanaged C/C++ project, how you call it is up to you. On another note, I should mention that it is also possible to call a C/C++ library (*.lib or COM DLL) directly from a C# project using DllImport, it's really up to you.
Inge Henriksen
+2  A: 

My company does something very similar, although with CCD cameras instead of line-scan cameras. We're using C# for the GUI, network communication, high-level "plumbing" and C++/CLI for the low-level algorithms. It works quite well. You'll never be able to write a true realtime system with guaranteed maximum response times on windows, but from my experience the GC will be the least of your problems here. For one thing, the GC only runs when you allocate memory; so does malloc/new in C/C++, and they need time, too (think memory fragmentation). From the measurements we've done, a full GC takes 10-50ms and will not neccessarily stop the other threads during that time (unless they try to allocate managed memory, I think), which is ok for us. But I'm not sure if these numbers can be generalized to any kind of application, you probably should do your own profiling to be sure.

If you're afraid that your GUI might break your realtime constraints, you might consider putting the actual image processing into a separate process and communicate with the GUI using pipes/sockets. Or at least keep that option in mind when you design your system, so you have it as a worst-case option, if you really run into unforseen performance problems.

Your second question was if you should use C++ or C# for the actual algorithms. Personally, I feel more comforatble in C++ when I write complex image processing algorithms. I think the language is better suited for the task, and there are far more numbercrunching libraries for C/C++ than for C#. But that might be a matter of personal preference. From a performance point of view, C++ has the advantage that the C++ inliner is better than the .NET JIT inliner (i.e. it can inline more of your small function calls).

If you choose to use C++, I'd suggest using C++/CLI: That way, you can write C++ classes that are compiled into managed code. The C++ optimizer will optimize them, only the last compilation step to native code will be done by the .NET JIT. The big advantage is that you can directly access your .NET classes from C++/CLI, and you can easily create managed classes in C++/CLI that can be accessed from C#. You don't need to write wrapper code on both sides of the fence. (C++/CLI is a bit clunky because it contains language constructs for managed and for unmanaged programming, but if you're already familiar with unmanaged C++ and C#, you probably won't have any problems understanding it.)

nikie
"and you can easily create managed classes in C++/CLI that can be accessed from C#"so, I've done this, but what if I want unmanaged code for the data-processing part? In my C++/CLI code, I'm guessing I'd write the unmanaged class to do everything, and then a C++/CLI interface that the C# calls, and can access my "pure" C++? Still just kinda confused here...
Jonathon Reinhart
That really depends on your problem. Writing unmanaged classes + managed wrappers in C++/CLI is one way. Writing small unmanaged helper functions and calling those from a larger managed class is also possible. The C++/CLI compiler can emit IL and native code, it can compile "normal" C++ and it has special keywords to create managed classes. The managed classes may call into the unmanaged code/create unmanaged classes and vice versa. How you use that is really up to you.
nikie
A: 

I've done it with C++.NET

Since both C++.NET and C# are managed I don't see why it could not be done. The point is how you will do it.

My scanner had up to 3000 lines / sec but the key strategy was to display blocks of 32 lines at a time. I didn't have hard real time requirements so I could be a little behind sometimes. If real time is very important to you, you should consider switching platform.

There is a real time windows solution called "InTime OS" but its really painful to use.

Another approach you can have is to separate the hard real time into a separate dll or library and have the C# show what it can at it's own speed. Really, the user will never be able to tell if your interface has 2000 fps or 500 fps

Eric
A: 

Why windows? It has horrible memory performance and worse network compared with any of the unixes out there. Specialized capture of a line sensor implies you need an appliance to handle the raw input. Consider using the right OS first which will greatly lower the other pressures you'll have to deal with (I'm am very very familiar with line scanner technologies).

Brian
Perhaps he doesn't want to try talking his customers into running something else than Windows?
erikkallen