Solved

Delphi multi-thread program apparenty not using a multi-core processor

Posted on 2013-01-05
10
4,116 Views
Last Modified: 2015-02-14
After decades of programming I am taking my first steps in parallel process programming using as always Delphi Professional, now XE3 on a Windows 8 professional Toshiba Satellite A665 laptop.
System.cpucount returns 4, as it should.
I have now programmed some minimal test programs and copied and tried some from the web running anywhere from 1 to 16 threads simultaneously. To my surprise the processing time is, however, just the same or somewhat greater than if I simply run the same processing sequentially. I wonder if the program is using all the cores or just one, whether some special switches have to be set, etc. (I have also read somewhere that Windows does not really allow parallel use of cores?)
0
Comment
Question by:magnussonms
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
  • 2
  • +2
10 Comments
 
LVL 27

Accepted Solution

by:
Sinisa Vuk earned 125 total points
ID: 38747561
It can be done. Make multitherading is not enough. You must assign each thread to specific processor core.
http://blogs.embarcadero.com/abauer/2008/02/22/38857
http://vitaliburkov.wordpress.com/2011/10/15/parallel-programming-in-delphi/
http://blogs.embarcadero.com/abauer/category/parallel-programming
some of components can help you to do job:
http://www.torry.net/pages.php?id=244
0
 
LVL 37

Assisted Solution

by:Geert Gruwez
Geert Gruwez earned 250 total points
ID: 38749198
you might want to check out the delphi geek's omni thread library
it's got a steep learning curve.
http://www.thedelphigeek.com/

it will take care of assigning the different threads to the different cpu
0
 
LVL 32

Expert Comment

by:Ephraim Wangoya
ID: 38751910
Consider
Multi-threading will not neccesarily increase your processing speed.
All depends on what type of processing you are doing, if one thread has to wait for resources beign used by another thread, then you dont get any speed advantage.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 38753819
threading has a lot of pitfalls
the most import items to pay attention:
1: protecting resources from simultaneous access
2: synchronisation of threads: like a thread can start when a other has finished

consider your program like a bath tub and all the people like threads
everybody has a task to do: take a bath
synchronisation is very important here:
>> you probably don't want everybody to take a bath together: the six kids + parents + grandparents
>> you need to set  certain rules like who can actually take a bath together

the data would be what items go in bath with the person:
rules need to be set here too: having a load of ducks in with the kids is nice,
but granddad will probably like it more if they are removed before he goes in
0
 
LVL 21

Expert Comment

by:developmentguru
ID: 38754511
It would help if we knew more about what you are attempting.

  Ray tracing is a great example of multiple processor cores being a great value.  In Ray tracing a great deal of math is done to render every pixel versus an in memory list of 3D objects.  Since each pixel can be rendered independently it would help to have thousands of cores.

  Other types of work are not easily threaded.  If you were doing database updates in a set of database tables that use foreign keys then each would need to wait until the previous had finished.  Without waiting until the previous one finished you would have errors from the same SQL updates that would not cause errors if other commands had finished.

  One of the biggest mistakes made by people new to multi-threading is trying to have all of the threads causing live screen updates.  Each update requires a synchronize statement.  This, in effect, makes all of the threads wait on each other.  If you need to have threads running, limit their updates of the screen to, something like once a second.
0
 

Author Comment

by:magnussonms
ID: 38755589
The task I am dealing with seems well suited for multi-cpu processing. It is basically the processing of independent samples where all the data and work arrays for each can be stored in a separate record, object etc. Each processor could thus work on a sample without any interaction with the others. (Actually, tasks within each also have this character providing another parallel processing approach.) The job would be finished when all the samples had been analyzed (using computation intensive pattern detection in each case, which should lend itself well to truly parallel processing). Moreover, there is no need for UI updating before the longest task has been completed. So, as far as I can see, this situation is a particularly well suited, rather like the ray tracing mentioned above (even more so).

Wile I have not done any parallel process programming until now, I have read about it for some time. As a matter of fact, my main research area during the last few decades is the analysis/modeling of real-time (social) interaction in humans, animals and brain-cells, developing and using highly optimized, but still computation hungry algorithms so I do not underestimate the the complexities of interactive parallelism, but the present case seems particularly simple.

It has come as a surprise to me that in Delphi (Professional XE3), assigning tasks to particular cpu-cores appears quite difficult at least partly due to the way Windows operates. Simply using parallel threads does not provide any speed advantage as I have now found out as sequential processing is easily faster while using much less processing (using sinisav's program). What I really need is a to assign each independent task to a separate core -- as its only (or main) task. I think this is at  the heart of my issue. I have read about the OTL library, which according to Geert_Gruwez above should allow this, but has a "steep learning curve". I will now continue studying it.

All the replies have been useful, but I am still looking for a realistic solution and I will write back when I have found it or postponed trying until better tools become available.
0
 
LVL 21

Assisted Solution

by:developmentguru
developmentguru earned 125 total points
ID: 38757459
I don't believe that Windows will allow you to hoard a processor for your thread.  You can assign a thread to a processor but there is no guarantee that nothing else will be scheduled on it.  You can up the priority to try to squeeze others out though.
0
 
LVL 37

Assisted Solution

by:Geert Gruwez
Geert Gruwez earned 250 total points
ID: 38758136
i built a very lightweight threading unit once:
check this Q
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_26193383.html#32795255

The question contains the uQueuedThreads unit.
Basically a FIFO queue monitored by a thread.
When a task is added to the queue, the monitor will start a new thread
the new thread will be given the information from the queued item

It doesn't contain Processor assignments yet.
This would be set in the thread create procedure

manually setting the thread affinity to the next cpu like this:
http://msdn.microsoft.com/en-us/library/ms686247%28v=VS.85%29.aspx

constructor TQueuedThread.Create(aInfo: TThreadQueueData; aOnThreadDone: TNotifyEvent);
begin
  inherited Create(False);
  FreeOnTerminate := True;
  OnTerminate := aOnThreadDone;
  fReturnInfoMsg := TStringList.Create;
  fInfo := aInfo;
  fReturnInfo := nil;
  if Assigned(aInfo) then
    fReturnInfo := aInfo.FReturnInfo;
  // set thread affinity to next cpu
  lCpu := lCpu*2; // or lCpu Shl 1
  if lCpu > lMaxCores then lCpu := 1;
  SetThreadAffinityMask(Handle, lCpu);
end;

Open in new window


lCpu is a variable in the uQueuedThread unit
lMaxCores also and initialised as

var
  info: TSystemInfo;
begin
  GetSystemInfo(info);
      lmaxCores := info.dwNumberOfProcessors;
end;

Open in new window

0
 

Author Closing Comment

by:magnussonms
ID: 38811578
I will need more time to find out what I can realistically do as my programming experience  is almost exclusively in Fortran and Delphi. Many thanks for most valuable help.
0
 
LVL 37

Expert Comment

by:Geert Gruwez
ID: 40609485
check the pipeline technique on OTL

I got some multi threading programs working with OTL, so i thought i'd come back on this.

 you indicated you need to process samples
pipeline lends itself to work in stages > first process is to get a sample, next process it (in different ways), capture the processed data and store it

pipeline := Parallel.PipeLine.Throttle(10000)
  .Stage(GetSample)
  .Stage(ProcessSample).NumTasks(4)
  .Stage(GatherProcessedData)
  .Stage(StoreResults)
  .Run;

Open in new window


Each procedure of the Stage is something like this:
procedure TDataProcessor.ProcessSample(const input, output: IOmniBlockingCollection;
  const task: IOmniTask);
var 
  Value: TOmniValue;
begin
    while not Task.Terminated do
    begin
      if input.TryTake(Value, 1000) then
      begin
        // Process the Value (can be any object)
        
        // when finished ... pass the calculated data to the next step
        repeat until TryAdd(ProcessedData, 1000);
      end;
  end;
end;

Open in new window

0

Featured Post

How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Cognitive Services 1 74
API v SOA 8 64
firemonkey Android Listview Sort items 7 106
Is there any way to treat Lock record in table with clientdataset? 3 46
Developer portfolios can be a bit of an enigma—how do you present yourself to employers without burying them in lines of code?  A modern portfolio is more than just work samples, it’s also a statement of how you work.
This article was originally published on Monitis Blog, you can check it here . If you have responsibility for software in production, I bet you’d like to know more about it. I don’t mean that you’d like an extra peek into the bowels of the sourc…
The viewer will learn how to successfully create a multiboot device using the SARDU utility on Windows 7. Start the SARDU utility: Change the image directory to wherever you store your ISOs, this will prevent you from having 2 copies of an ISO wit…
XMind Plus helps organize all details/aspects of any project from large to small in an orderly and concise manner. If you are working on a complex project, use this micro tutorial to show you how to make a basic flow chart. The software is free when…

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question