可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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 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 Stack Overflow...
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.
回答1:
There is no reason that you can't write high performance code entirely in C#.
Performance (C# Programming Guide)
Rico Mariani's Performance Blog (an excellent resource)
Tuning .NET Application Performance
SO questions on the same/similiar topic:
- C++ performance vs. Java/C#
- How much faster is c++ than c#?
Other articles:
- Microbenchmarking C++, C#, and Java
- Harness the Features of C# to Power Your Scientific Computing Projects
- Find Application Bottlenecks with Visual Studio Profiler
- Debunking C# vs C++ Performance
回答2:
In my opinion your solution is a sound one:
- 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
- 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/.
回答3:
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 !
回答4:
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.
回答5:
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.)
回答6:
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?
回答7:
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.
回答8:
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).
回答9:
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
回答10:
I have an experience in native C/C++ and C# very low latency systems.
in C/C++ 80 % of processor time is lost in deterministic malloc methods, but native code is 10x faster than msil code
in C# memory allocation is faster because it is a asynchrone process
Your choice must be done by the ratio : process time / malloc number
So Granularity !!!
The solution for C/C++ is pre-alloc alls buffers in memory (use prefetch L2/L3 cache if necessary)
The solution for C# is minimize P-Invoke conversion mechanism
Congratulations for your project, Paul
回答11:
Front end wpf and c++ backend (pinvoke) is fast but when you do your GUI work on threads as well, your GUI thread doesn't get blocked by your background code. When you do that your program will look faster and light weight.
回答12:
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).