News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

multicore

Started by uhuru5895, September 22, 2012, 10:15:45 AM

Previous topic - Next topic

uhuru5895

Could someone point me to some working examples of multicore or parallel processing in assembly
Thanks in advance

hutch--

In the simple sense you perform this task with multi-thread code. There are many options here depending on what you have in mind. The current version of MASM32 has a few multi-thread examples but of course there are almost endless possibilities on what you can do with multi-threading. There is also some hardware based code available where you set a thread to a core when you are doing critical work.

CodeDog

There are two different concepts of parallel execution. You could be talking about executing instructions from two different execution units at the same time such as the ALU and FPU on a single core or you could be talking about executing instructions from two different cores at the same time. In the latter context you need to create a second thread (or more, depending on the number of processors in the system)

To retrieve the number of processors in the system you have to define a structure like this and run this api function:

lol proc
local sysinfo:SYSTEM_INFO
invoke GetSystemInfo, ADDR sysinfo
mov eax, sysinfo.dwNumberOfProcessors
; eax now contains amount of logical cores in the system (which is equal to amount of physical cores if hyperthreading is not present)
lol endp


If your system have HT you can detect it by using the cpuid instruction. To execute instructions in two threads, you simply create a given number of extra threads and begin executing instructions in them. You create a thread this way:

..
..
invoke CreateThread,NULL,0,OFFSET ThreadProc,ExtraVar,0
mov ThreadHandle,eax   ; save handle of thread
..
..



ThreadProc lpParameter:dword
  ...
  ...
  ...
somelabel:
  .IF GlobalVariable==TRUE
      ret
  .ENDIF
  do some work here
  ...
  ...
  ...
ThreadProc endp


In your main thread, you can set GlobalVariable to TRUE when you want the other thread to stop executing, like this:

...
...
  mov GlobalVariable,TRUE
  invoke WaitForSingleObject,ThreadHandle,1000   ; this will wait until the thread has returned before continuing in the main thread, or timeout at one second. Never use INFINITE here.
...

Now you're ready to shutdown the program, remember to close the thread handle.

qWord

A very simple example for a dual core processor:
include \masm32\include\masm32rt.inc
.code
core0 proc pvoid:PVOID

; do whatever
invoke ExitThread,0
core0 endp

core1 proc pvoid:PVOID

; do whatever
invoke ExitThread,0
core1 endp

main proc
LOCAL hThread[2]:HANDLE
LOCAL thread0:DWORD
LOCAL thread1:DWORD

mov hThread[0],rv(CreateThread,0,0,core0,0,CREATE_SUSPENDED,ADDR thread0)
mov hThread[4],rv(CreateThread,0,0,core1,0,CREATE_SUSPENDED,ADDR thread1)
invoke SetThreadAffinityMask,hThread[0],1
invoke SetThreadAffinityMask,hThread[4],2
invoke ResumeThread,hThread[0]
invoke ResumeThread,hThread[4]
invoke WaitForMultipleObjects,2,ADDR hThread,TRUE,INFINITE

invoke ExitProcess,0
main endp
end main
MREAL macros - when you need floating point arithmetic while assembling!

CodeDog

Nice example qWord, for this specific example you can wait infinitely for the threads to exit but should only be used if you absolutely know what the thread is doing or you may risk running into a dead lock. I always put a 1000-3000 ms wait time there. The exitthread is a good way to exit the thread but it is not necessary to do so, in fact it adds one more api call and slows it down (not much anyway, but it adds more slow). The affinity mask should be avoided because it will produce unpredictable sharing of processor time and the system can't spread it to the core that has the least load. It may seem like an elegant way to do it but it is best left to the system to judge. But I like your sample, its short and good.  :eusa_naughty:

qWord

Quote from: CodeDog on September 24, 2012, 11:41:39 PMbut it is not necessary to do so, in fact it adds one more api call and slows it down
No, quite the opposite: it speeds up the process because it avoids unnecessary instructions.
Quote from: CodeDog on September 24, 2012, 11:41:39 PMThe affinity mask should be avoided because it will produce unpredictable sharing of processor time and the system can't spread it to the core that has the least load.
The load of running threads is allways unpredictable for the OSs. Regardless that, the question was about multicore processing.
MREAL macros - when you need floating point arithmetic while assembling!

CodeDog

We can talk multicore regardless of forcing it to run on the same cores, it's just that the system selects which core to use. If everybody coded their application to force threads running on specific cores there would be a problem if it became popular. Your idea is good for secret programming but not for the public. Imagine ten programs running on the same cores on your computer, locked, glued and stubborn.  :bgrin:

I have not counted cycles taken for exitthread api call, it may or may not be that it runs faster but it is not necessary and if we follow standard programming logic, removing it should be faster, but it doesn't matter as both ways work and exitthread is a good way of shutting down. Just don't teach people bad habits.

CodeDog

Quote from: qWord on September 25, 2012, 12:58:11 AM
The load of running threads is allways unpredictable for the OSs. Regardless that, the question was about multicore processing.

The OS doesn't have to know, it only needs to spread the load equally, then it would also automatically know that resources are shared in a somewhat rational way. Something like 4 buckets of apples, if you grab a handfull from each bucket and throw it to the dogs, you know that you are sharing apples, you don't know how much you are sharing, you only know sharing is happening and that it is better than not sharing at all.

qWord

Quote from: CodeDog on September 25, 2012, 01:55:35 AMYour idea is good for secret programming but not for the public.
Oh year, *my idea* should be kept secret.

Quote from: CodeDog on September 25, 2012, 01:55:35 AMand if we follow standard programming logic, removing it should be faster .... Just don't teach people bad habits.
You should think about things, before putting somebody right.
MREAL macros - when you need floating point arithmetic while assembling!

CodeDog

Quote from: qWord on September 25, 2012, 02:20:19 AM

You should think about things, before putting somebody right.

What kind of things, specifically?  :biggrin:

qWord

Quote from: CodeDog on September 25, 2012, 02:35:36 AMWhat kind of things, specifically?  :biggrin:
Well, as an expert you should know that returning from a thread also end up in a call to ExitThread  ;)
MREAL macros - when you need floating point arithmetic while assembling!

CodeDog

If programming was always about being right we wouldn't need a forum like this. I'm not an expert btw ( I claim the right to ask silly questions at a later stage  :greensml:), I'm still learning assembly. But then again API functionality isn't so much about assembly.

My current project is Nibbles: (lol)


hutch--

CD,

is there some point to posting an image of a large black window ?