Increase process flow and priority to reduce runtime for intensive, parallel processor applications

I know that setting thread priority is a bit of a taboo topic when stack overflowing, but I am convinced that my application is a good candidate for increasing priority. To justify this, I explained the context below. The question is HOW to do this effectively?

The application is a .NET 4 console application (C #), which performs a complex algorithm with a runtime of about five hours. The algorithm does not require intensive work with memory at all, but just an intensive processor. It crunches and does not perform any I / O, database connection, network connection, etc. The output of the application is just ONE number that it writes to the console at the end. In other words, the algorithm is completely autonomous and has no dependencies.

The application runs on its own dedicated 16-bit 64-bit machine running Windows Server with much more free RAM than required (8 GB). By special, I mean that the server was purchased to run this application EXCLUSIVELY.

I have already optimized the code as much as I could, with extensive profiling, fancy math shortcuts and bit tricks.

Here is the general structure in pseudocode:

public static void Main () { Process.GetCurrentProcess().PriorityBoostEnabled = true; Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime; // Of course this only affects the main thread rather than child threads. Thread.CurrentThread.Priority = ThreadPriority.Highest; BigInteger seed = SomeExtremelyLargeNumber; // Millions of digits. // The following loop takes [seed] and processes some numbers. result1 = Parallel.For(/* With thread-static variables. */); while (true) // Main loop that cannot be parallelized. { // Processes result1. result2 = Parallel.For(/* With thread-static variables. */); // Processes result2. result1 = Parallel.For(/* With thread-static variables. */); if (result1 == criteria) break; // Note: This loop does not need to sleep or care about system responsiveness. } } 

Now, based on issues related to thread priority on SO, I understand that using ThreadPool should not be confused with priority. Therefore, if I need to switch to manual flows, so be it.

Question:

  • How do I change the code above to manual threading to benefit from increasing the priority of the thread (without using the thread pool, etc.)?
  • Does setting the highest priority on all child threads help? I mean, will the child threads fight each other or will this give them an edge over the external tasks of the OS?
  • Given that there are 16 cores, should I run 16 or 15 threads? Is there a general rule for this?
  • Will the tuning process be prioritized for real-time help?
+4
source share
3 answers

With such an application, I would expect a change in priorities to make a 0% difference with the total execution time. If you have already reached the maximum return on CPU utilization with all 16 cores at 100% real work, you cannot do more.

+2
source

You don’t have to worry about setting priority for individual threads, just do it for the whole process, as most of its threads really do the important work.

However , I do not expect this to make a difference for processor intensive applications like yours. The only processes that can force out your own process are intensive I / O applications, which most OSs traditionally prefer, but since you have a dedicated computer, this will not be a problem (also Windows Server is quite lightweight in my experience, so it doesn't will interfere if your application runs only one.)

As a note:

The algorithm does not have a large amount of memory at all, just the processor is intense. It crunches and does not perform any I / O, database connection, network connection, etc.

The fact that it does not perform the “obvious” I / O operations does not mean that it cannot be memory intensive. If you process large arrays or other data structures, the CPU will constantly issue read / write operations to the main memory, and a lot of work is done to move the data between different memory levels. Even working with numbers can adversely affect program performance if it is performed incorrectly.

+1
source

I expect you to limit the number of threads to the number of cores / threads. Sometimes the parallel task library uses too many threads. For your cpumaxed process, it is best to use either corecount or threadcount (adding fakecores hyperthreads), so put and fix threadcount;

  // Create a ParallelOptions object and supply this to the Parallel.For() var po = new ParallelOptions {MaxDegreeOfParallelism = Environment.ProcessorCount} Parallel.For(,,po,); // Environment.ProcessorCount gives number of Cores (NOT processors) // Never found out how to detect fake cores or hyperthreads, check Task Monitor ;-) 

You can reuse the po object for all parallel.For () statements. I have never benefited from a priority game, even on processors tied to streaming applications.

0
source

All Articles