Wrapping unmanaged code using multiple processors - c#

I have an existing application written in c++ that does a number of tasks currently, reading transactiosn from a database for all customers, processing them and writing the results back.
What I want to do is have multiple versions of this running in parallel on separate machines to increase transaction capacity, by assigning a certain subset of customers to each version of the app so that there is no contention or data sharing required, hence no locking or synchronisation.
What I want to do though is have multiple versions running on the same machine aswell as distributed across other machines, so if I have a quad core box, there would be four instances of the application running, each utilising one of the CPU's.
I will be wrapping the c++ code in a .NET c# interface and managing all these processes - local and distributed from a parent c# management service responsible for creating, starting and stopping the processes, aswell as all communication and management between them.
What I want to know is if I create four instances each on a separate background thread on a quad core box, whether or not the CLR and .NET will automatically take care of spreading the load across the four CPUs on each box or whether I need to do something to make use of the parallel processing capability?

If you mean that you will be running your application in four processes on the same box, then it is the operating system (Windows) which controls how these processes are allocated CPU time. If the processes are doing similar work, then generally they will get roughly equal processor time.
But, have you considered using four threads within a single process? Threads are much more lightweight than processes, and you wouldn't then need a separate management service, i.e., you would have one process (with four threads) instead of 5 processes. Do you come from a unix background by any chance?

You can set the process affinity when launching the process via the Process object (or ProcessThread depending on how you are launching the app).
Here is an SO post which covers the subject (I didn't vote to close as a duplicate (yet) because I'm not 100% sure if this is exactly what you are after).

Related

Force simultaneous threads/tasks for C# load testing app?

Question:
Is there a way to force the Task Parallel Library to run multiple tasks simultaneously? Even if it means making the whole process run slower with all the added context switching on each core?
Background:
I'm fairly new to multithreading, so I could use some assistance. My initial research hasn't turned up much, but I also doubt I know what exactly to search for. Perhaps someone more experienced with multithreading can help me better understand TPL and/or find a better solution.
Our company is planning on deploying a piece of software to all users' machines that will connect to a central server a few times a day, and synchronize some files and MS Access data back to the user's machine. We would like to load-test this concept first and see how the Access DB holds up to lots of simultaneous connections.
I've been tasked with writing a .NET application that behaves like the client app (connecting & syncing with a network location), but does this on multiple threads simultaneously.
I've been getting familiar with the Task Parallel Library (TPL), as this seems like the best (newest) way to handle multithreading, and get return values back from each thread easily. However as I understand it, TPL decides how to run each "task" for the fastest execution possible, splitting the work among the available cores. So lets say I want to run 30 sync jobs on a 2-core machine... the TPL would run 15 on each core, sequentially. This would mean my load test would only be hitting the Access DB with at most 2 connections at the same time. I want to hit the database with lots of simultaneous connections.
You can force the TPL to do this by specifying TaskOptions.LongRunning. According to Reflector (not according to the docs, though) this always creates a new thread. I consider relying on this safe production use.
Normal tasks will not do, because they don't guarantee execution. Setting MinThreads is a horrible solution (for production) because you are changing a process global setting to solve a local problem. And still, you are not guaranteed success.
Of course, you can also start threads. Tasks are more convenient though because of error handling. Nothing wrong with using threads for this use case.
Based on your comment, I think you should reconsider using Access in the first place. It doesn't scale well and has problems once the database grows to a certain size. Especially if this is simply served off some file share on your network.
You can try and simulate load from your single machine but I don't think that would be very representative of what you are trying to accomplish.
Have you considered using SQL Server Express? It's basically a de-tuned version of the full-blown SQL Server which might suit your needs better.

Control Memory-Hungy Multi-Threaded App

This a VERY open question.
Basically, I have a computing application that launches test combinations for N Scenarios.
Each test is conducted in a single dedicated thread, and involves reading large binary data, processing it, and dropping results to DB.
If the number of threads is too large, the app gets rogue and eats out all available memory and hangs out..
What is the most efficient way to exploit all CPU+RAM capabilities (High Performance computing i.e 12Cores/16GB RAM) without putting the system down to its knees (which happens if "too many" simultaneous threads are launched, "too many" being a relative notion of course)
I have to specify that I have a workers buffer queue with N workers, every time one finishes and dies a new one is launched via a Queue. This works pretty fine as of now. But I would like to avoid "manually" and "empirically" setting the number of simultaneous threads and have an intelligent scalable system that drops as many threads at a time that the system can properly handle, and stop at a "reasonable" memory usage (the target server is dedicated to the app so there is no problem regarding other applications except the system)
PS : I know that .Net 3.5 comes with Thread Pools and .Net 4 has interesting TPL capabilites, that I am still considering right now (I never went very deep into this so far).
PS 2 : After reading this post I was a bit puzzled by the "don't do this" answers. Though I think such request is fair for a memory-demanding computing program.
EDIT
After reading this post I will to try to use WMI features
All built-in threading capabilities in .NET do not support adjusting according to memory usage. You need to build this yourself.
You can either predict memory usage or react to low memory conditions. Alternatives:
Look at the amount of free memory on the system before launching a new task. If it is below 500mb, wait until enough has been freed.
Launch tasks as they come and throttle as soon as some of them start to fail because of OOM. Restart them later. This alternative sucks big time because your process will do garbage collections like crazy to avoid the OOMs.
I recommend (1).
You can either look at free system memory or your own processes memory usage. In order to get the memory usage I recommend looking at private bytes using the Process class.
If you set aside 1GB of buffer on your 16GB system you run at 94% efficiency and are pretty safe.

Batch Processing on Multiple Servers

There is a multi threaded batch processing program, that creates multiple worker threads to process each batch process.
Now to scale the application to handle 100 million records, we need to use a server farm to do the processing of each batch process. Is there native support on C# for handling requests running on a server farm? Any thoughts on how to setup the C# executable to work with this setup?
You can either create a manager that distributes the work like fejesjoco said or you can make your apps smart enough to only grab a certain number of units of work to process on. When they have completed processing of those units, have them contact the db server to get the next batch. Rinse and repeat until done.
As a side note most distributed worker systems run by:
Work is queued in server by batches
Worker Processes check in with server to get a batch to operate on, the available batch is marked as being processed by that worker.
(optional) Worker Processes check back in with server with status report (ie: 10% done, 20% done, etc)
Worker process completes work and submits results.
Go to step 2.
Another option is to have 3 workers process the exact same data set. This would allow you to compare results. If 2 or more have identical results then you accept those results. If all 3 have different results then you know there is a problem and you need to inspect the data/code. Usually this only happens when the workers are outside of your control (like SETI) or you are running massive calculations and want to correct for potential hardware issues.
Sometimes there is a management app which displays current number of workers and progress with entire set. If you know roughly how long an individual batch takes then you can detect when a worker died and can let a new process get the same batch.
This allows you to add or remove as many individual workers as you want without having to recode anything.
I don't think there's builtin support for clustering. In the most simple case, you might try creating a simple manager application which divides the input among the servers, and your processes will not need to know about each other, so no need to rewrite anything.
Why not deploy the app using a distributed framework? I'd recommend CloudIQ Platform You can use the platform to distribute your code to any number of servers. It also handles the load balancing, so you would only need to submit your jobs to the framework, and it will handle job distribution to the individual machines. It also monitors application execution, so if one of the machines suffers a failure, the jobs running there will be restarted on another machine in the group.
Check out the Community link for downloads, forums, etc.

Building C# console app for multiple instances

I'm building a console application which imports data into databases. This is to run every hour depending on an input CSV file being present. The application also needs to be reused for other database imports on the same server, e.g. there could be up to 20 instances of the same .exe file with each instance having their own separate configuration.
At the moment I have the base application which passes a location of config file via args, so it can be tweaked depending on which application needs to use it. It also undertakes the import via a transaction, which all works fine.
I'm concerned that having 20 instances of the same .exe file running on the same box, every hour, may cause the CPU to max out?
What can I do to resolve this? Would threading help?
Why not make a single instance that can handle multiple configurations? Seems a lot easier to maintain and control.
Each executable will be running in it's own process, and therefore, with it's own thread(s). Depending on how processor intensive each task is, the CPU may well max out but this is not necessarily something to be concerned about. If you are concerned about concurrent load then the best way may be to stagger the scheduling of your processes so that you have the minimum number of them running simultaneously.
No, this isn't a threading issue.
Just create a system-wide named Mutex at the start of the application. When creating that Mutex, see if it already exists. If it does, it means that there is another instance of your application running. At this point you can give the user a message (via the console or message box) to say that another instance is already running, then you can terminate the application.
I realize this thread is very old but I had the very same issues on my project. I suggest using MSMQ to process jobs in sequence.

How can an application use multiple cores or CPUs in .NET or Java?

When launching a thread or a process in .NET or Java, is there a way to choose which processor or core it is launched on? How does the shared memory model work in such cases?
If you're using multiple threads, the operating system will automatically take care of using multiple cores.
is there a way to choose which processor or core it is launched on?
You can use the task manager to tell windows what CPU(s) your program should be allowed to run on. Normally this is only useful for troubleshooting legacy programs which have broken implementations of multi-threading. To do this,
Run task manager
Find your process in the Processes window.
Right click and choose Set Affinity...
Tick the checkboxes next to the CPU's you want to allow your application to run on. Windows will then only schedule threads from that process onto those particular CPU's
If I recall correctly, windows will 'remember' these settings for subsequent times your process is run, but please don't quote me on that - run some tests yourself :-)
You can also do this programatically in .NET after your program has launched using using the System.Diagnostics.Process.ProcessorAffinity property, but I don't think it will 'remember' the settings, so there will always be a short period in which your app is run on whichever CPU windows sees fit. I don't know how to do this in java sorry.
Note:
This applies at the entire process level. If you set affinity for CPU0 only, and then launch 50 threads, all 50 of those threads will run on CPU0, and CPU1, 2, 3, etc will sit around doing nothing.
Just to reiterate the point, this is primarily useful for troubleshooting broken legacy software. If your software is not broken, you really shouldn't mess with any of these settings, and let windows decide the best CPU(s) to run your program on, so it can take the rest of the system's performance into account.
As for the 'shared memory' model, it works the same, but there are more things that can go subtly wrong when your app is running on multiple CPU's as opposed to just timeslices on a single one.
For an eye-opening example, read this ridiculousfish article about CPU's and Memory Barriers.
It's aimed at OSX development on PowerPC, but general enough that it should apply everywhere. IMHO it's one of the top ten 'all developers should read this' articles I've read.
The operating system takes care of multi-threading when the virtual machine is using native threads (as opposed to green-threads), and you can't specify low level details, like choosing a processor for a certain thread. It is better that way because you usually have many more threads than you have processors available, so the operating system needs to do time-slicing to give all threads a chance to run.
That being said, you can set threads priorities if you have a critical task, and a threading API usually provides this possibility. See the Java API for example: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.html#setPriority(int)
PS: there's something broken in the parsing engine ... I had to add the above link as plain text
I would have a look at the Parallel extensions to the .NET framework. It is still in CTP, however it supposed to make the best use of multi core processors. The easiest place to get started for .NET is on the parallel teams blog.
As for Java I have no idea.
I have used this in a couple of programs because my core 0 was kind of messed up.
// Programmatically set process affinity
var process = System.Diagnostics.Process.GetCurrentProcess();
// Set Core 0
process.ProcessorAffinity = new IntPtr(0x0001);
or
// Set Core 1
process.ProcessorAffinity = new IntPtr(0x0002);
More on this in "Process.ProcessorAffinity Property".

Categories

Resources