Tuesday, May 26, 2015

Digest for comp.programming.threads@googlegroups.com - 8 updates in 4 topics

Ramine <ramine@1.1>: May 25 02:14PM -0700

Hello,
 
 
You have to know that to design and implement an efficient Threadpool as
my efficient Threadpool engine with priorities that is correct and
efficient, it is somewhat a hard job, so to facilitate the reasonning
about concurrent programming i have used my scalable AMLock around a
small portion of the TPThreadPoolThread.Execute() method of my efficient
Threadpool engine with priorities to facilitate the reasonning about
"correctness", and i think that now that my new algorithm has
facilitates the reasonning about correctness and now that i have tested
it thoroughly , you can be more confident cause i think that my new
algorithm of my efficient Threadpool engine with priorities is correct
and stable now and it is also fast.
 
And look at the ThreadPoolExecutor Class of Java, look for example at
the awaitTermination() method, it says:
 
---
boolean awaitTermination(long timeout, TimeUnit unit)
 
Blocks until all tasks have completed execution after a shutdown
request, or the timeout occurs, or the current thread is interrupted,
whichever happens first.
--
 
read more here:
 
https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html#method.summary
 
Did you notice ?
 
In Java when you wait for the tasks you have to wait for "ALL" the
tasks, and that's not efficient , and if you want to use the object from
multiple threads i think it will have the same effect, you can avoid
some of the problems by using many objects of the ThreadPoolExecutor
class but this will take ressources and this will cause more and more
context switches and that's bad, i think C# has the same problem, other
than that Java and C# don't support priorities, it means that you can
not give priorities to tasks/jobs, like high or normal or low, and
that's not good for games and other applications where you have to use
priorities even if the system is not a realtime system, this is why i
have decided to implement my efficient Threadpool engine version 2.1
that supports those characteristics, so that you can create a child
object of the Threadpool class that will use the same worker threads and
that will wait only for the tasks that you will add with the execute()
method , and also my efficient Threadpool engine supports 3 priorities,
High and normal and low, that's where my efficient Threadpool engine
comes in hand and that's where it's efficient. Hope you will like it.
 
I will talk about an important subject that is software "reliability",
you have seen me explaining to you what is that it's efficient and
reliable with my efficient Threadpool engine, and you have seen me
talking to you about the automaton of my efficient Threadpool engine ,
this automaton takes care of software "reliability", like in design by
contracts that takes care of realiability, i have finally been able to
render my efficient Threadpool engine a reliable software by using an
automaton that "guides" you by helping you to avoid forbidden
transitions that can cause problems like deadlocks and dangerous
problems, my automaton has made my efficient threadpool engine a
reliable software, i explain more: since i am using 3 methods called
execute() that distributes the jobs to the worker threads and i am using
also setCounter() method with a boolean as a parameter and using also
wait() method that waits for the jobs to finish (this look like a
join()) with two parameters, but what i have noticed is that you can
call those methods by combining them in a different ways , but this can
cause some combinations that are forbidden to be called and that can
cause deadlock or dangerous problems, this is why i have wrote an
automaton that help you and guide you by using also exception handling
to use the right combinations of those methods and there parameters, so
like in design by contracts, my automaton has made my efficient
Threadpool engine a reliable software. Please read the HTML tutorial
inside the zip file to understand how to use the execute() and
setCounter() and wait() methods etc.
 
 
You can download my efficient Threadpool engine from:
 
 
https://sites.google.com/site/aminer68/threadpool-with-priorities
 
 
 
Thank you,
Amine Moulay Ramdane.
bleachbot <bleachbot@httrack.com>: May 25 05:35PM +0200

bleachbot <bleachbot@httrack.com>: May 25 06:35PM +0200

bleachbot <bleachbot@httrack.com>: May 25 06:54PM +0200

bleachbot <bleachbot@httrack.com>: May 25 08:12PM +0200

Ramine <ramine@1.1>: May 25 12:36PM -0700

Hello,
 
 
Here is my efficient Threadpool engine tutorial
 
 
On a multicore system, your goal is to spread the work efficiently among
many cores so that it does executes simultaneously. And performance gain
should be directly related to how many cores you have. So, a quad core
system should be able to get the work done 4 times faster than a single
core system. A 16-core platform should be 4-times faster than a
quad-core system, and 16-times faster than a single core...
 
That's where my efficient Threadpool is useful , it spreads the work
efficiently among many cores. Threadpool (and Threadpool with
priorities) consist of a fast concurrent FIFO queue, so when you call
ThreadPool.execute() , your work item get queued in thethe fast
concurrent queue. The worker threads pick them out in a First In First
Out order (i.e., FIFO order), and execute them.
 
 
The following have been added to the efficient Threadpool engine:
 
* The worker threads enters in a wait state when there is no job in
the concurrent FIFO queues - for more efficiency -
* You can distribute your jobs to the worker threads and call any
method with the threadpool's execute() method.
* You can wait for the jobs to finish with the wait() method.
 
 
My Threadpool allows load balancing, and also minimize contention.
 
 
Threadpool is very easy to use, let's look now at an example in Object
Pascal...
 
program test;
 
 
 
uses
 
{$IFDEF Delphi}
 
cmem,
 
{$ENDIF}
 
ThreadPool,sysutils,syncobjs;
 
{$I defines.inc}
 
type
 
TMyThread = class (TThreadPoolThread)
 
//procedure ProcessRequest(obj: Pointer); override;
 
procedure MyProc1(obj: Pointer);
 
procedure MyProc2(obj: Pointer);
 
end;
 
 
 
var
 
myobj:TMyThread;
 
TP: TThreadPool;
 
obj:pointer;
 
cs: TCriticalSection;
 
tp1:TThreadPoolC;
 
 
 
 
procedure TMyThread.MyProc1(obj: Pointer);
 
begin
 
cs.enter;
 
writeln('This is MyProc1 with parameter: ',integer(obj));
 
cs.leave;
 
end;
 
procedure TMyThread.MyProc2(obj: Pointer);
 
begin
 
cs.enter;
 
writeln('This is MyProc2 with parameter: ',integer(obj));
 
cs.leave;
 
end;
 
begin
 
myobj:=TMyThread.create;
 
cs:=TCriticalSection.create;
 
TP := TThreadPool.Create(4, TMyThread); // 4 workers threads.
 
tp1:=TP.CreateThreadPoolC(true);
 
obj:=pointer(1);
 
TP1.execute(myobj.myproc1,pointer(obj));
 
obj:=pointer(2);
 
TP1.execute(myobj.myproc2,pointer(obj));
 
TP1.setCounter() ;
 
TP1.wait(INFINITE);
 
readln;
 
TP1.free;
 
TP.Terminate;
 
TP.Free;
 
end.
 
 
 
Let us look at the first line...
 
uses
 
{$IFDEF Delphi}
 
cmem,
 
{$ENDIF}
 
cmem is required for Delphi to use TBB memory manager (from Intel) ,
this will allow delphi memory manager to scale linearely...
 
Note: FPC doesn't need cmem, cause it scales linearely with threads...
 
ThreadPool: is our threadpool unit ..
 
syncobjs: contains all the sychronizations stuff like CriticalSections,
Events etc..
 
After that we have the following lines:
 
type
 
TMyThread = class (TThreadPoolThread)
 
//procedure ProcessRequest(obj: Pointer); override;
 
procedure MyProc1(obj: Pointer);
 
procedure MyProc2(obj: Pointer);
 
end;
 
We declare a TMyThread that ineherit from TThreadPoolThread, and we
declare our two methods MyProc1 and MyProc2 that we want to be executed
by our threadpool's worker threads. Each method has an obj as a paramater.
 
In the main body we create a TMyThread object like this:
 
myobj:=TMyThread.create;
 
and after that we create a TThreadPool object with 4 workers threads
like this:
 
TP := TThreadPool.Create(4, TMyThread); // 4 workers threads.
 
After that you create ThreadPoolC object so that you can distribute your
jobs to the ThreadPool by writing this:
tp1:=TP.CreateThreadPoolC(true);
 
If you pass true to CreateThreadPoolC() , wait() will wait for all the
jobs to finish, if you pass false to CreateThreadPoolC(), wait() will
not wait for the jobs to finish.
 
After that we distribute to our worker threads the methods to be
executed , we do it by calling the Threadpool's execute() method and we
pass it myobj.myproc1 and myobj.myproc2 with there parameters:.
After that you have to call setCounter() and wait() to wait for all the
threads..
 
TP.1.setCounter();
 
TP1.wait(INFINITE);
You have to call setCounter() , it is mandatory, the first parameter of
wait() is the time to wait in milliseconds, if you set it to INFINITE,
it will wait for the threads to finish.
 
After that you have to free TP1 and TP objects.
 
As you see, Threadpool (and threadpool with priority) is very easy to use...
 
Let's look now at an example of a Threadpool with priority:.
 
program test;
 
 
 
uses
 
{$IFDEF Delphi}
 
cmem,
 
{$ENDIF}
 
PThreadPool,sysutils,syncobjs;
 
{$I defines.inc}
 
type
 
TMyThread = class (TPThreadPoolThread)
 
//procedure ProcessRequest(obj: Pointer); override;
 
procedure MyProc1(obj: Pointer);
 
procedure MyProc2(obj: Pointer);
 
end;
 
 
 
var
 
myobj:TMyThread;
 
TP: TPThreadPool;
 
obj:pointer;
 
cs:TCriticalSection;
 
tp1:TPThreadPoolC;
 
procedure TMyThread.MyProc1(obj: Pointer);
 
begin
 
cs.enter;
 
writeln('This is MyProc1 with parameter: ',integer(obj));
 
cs.leave;
 
end;
 
procedure TMyThread.MyProc2(obj: Pointer);
 
begin
 
cs.enter;
 
writeln('This is MyProc2 with parameter: ',integer(obj));
 
cs.leave;
 
end;
 
begin
 
myobj:=TMyThread.create;
 
cs:=TCriticalSection.create;
 
TP := TPThreadPool.Create(4,TMyThread, 20); // 4 workers threads and
2^20 items for each queue.
 
tp1:=TP.CreateThreadPoolC(true);
 
obj:=pointer(1);
 
TP1.execute(myobj.myproc1,pointer(obj),NORMAL_PRIORITY);
 
obj:=pointer(2);
 
TP1.execute(myobj.myproc2,pointer(obj),NORMAL_PRIORITY);
 
TP1.setCounter();
 
TP1.wait(INIFINITE);
 
readln;
 
TP.Terminate;
 
TP.Free;
 
end.
 
 
As you have noticed, this is almost the same as threadpool..
 
You use PThreadPool - P for priority - rather than Threadpool
 
TPThreadPoolThread rather than TThreadPoolThread
 
TPThreadPoolC rather than TThreadPoolC
 
TPThreadPool.Create rather than TThreadPool.Create
 
and as you have noticed in
TP.execute(myobj.myproc1,pointer(obj),NORMAL_PRIORITY) we are using
priorities.
 
You can give the following priorities to jobs:
 
LOW_PRIORITY
NORMAL_PRIORITY
HIGH_PRIORITY
 
 
 
That's all.
 
You can download threadpool (and threadpool with priority) from:
 
https://sites.google.com/site/aminer68/
 
Sincerely,
Amine Moulay Ramdane.
Ramine <ramine@1.1>: May 25 12:55PM -0700

Hello,
 
 
Here is the new updated tutorial:
 
 
On a multicore system, your goal is to spread the work efficiently among
many cores so that it does executes simultaneously. And performance gain
should be directly related to how many cores you have. So, a quad core
system should be able to get the work done 4 times faster than a single
core system. A 16-core platform should be 4-times faster than a
quad-core system, and 16-times faster than a single core...
 
That's where my efficient Threadpool is useful , it spreads the work
efficiently among many cores. Threadpool (and Threadpool with
priorities) consist of a fast concurrent FIFO queue and a number of
worker threads that you have to start, so when you call
ThreadPool.execute() , your work item get queued in the fast concurrent
queue. The worker threads pick them out in a First In First Out order
(i.e., FIFO order), and execute them.
 
 
The following have been added to the efficient Threadpool engine:
 
* The worker threads enters in a wait state when there is no job in
the concurrent FIFO queues - for more efficiency -
* You can distribute your jobs to the worker threads and call any
method with the threadpool's execute() method.
* You can wait for the jobs to finish with the wait() method.
 
 
My Threadpool allows load balancing, and also minimize contention.
 
 
Threadpool is very easy to use, let's look now at an example in Object
Pascal...
 
program test;
 
 
 
uses
 
{$IFDEF Delphi}
 
cmem,
 
{$ENDIF}
 
ThreadPool,sysutils,syncobjs;
 
{$I defines.inc}
 
type
 
TMyThread = class (TThreadPoolThread)
 
//procedure ProcessRequest(obj: Pointer); override;
 
procedure MyProc1(obj: Pointer);
 
procedure MyProc2(obj: Pointer);
 
end;
 
 
 
var
 
myobj:TMyThread;
 
TP: TThreadPool;
 
obj:pointer;
 
cs: TCriticalSection;
 
tp1:TThreadPoolC;
 
 
 
 
procedure TMyThread.MyProc1(obj: Pointer);
 
begin
 
cs.enter;
 
writeln('This is MyProc1 with parameter: ',integer(obj));
 
cs.leave;
 
end;
 
procedure TMyThread.MyProc2(obj: Pointer);
 
begin
 
cs.enter;
 
writeln('This is MyProc2 with parameter: ',integer(obj));
 
cs.leave;
 
end;
 
begin
 
myobj:=TMyThread.create;
 
cs:=TCriticalSection.create;
 
TP := TThreadPool.Create(4, TMyThread); // 4 workers threads.
 
tp1:=TP.CreateThreadPoolC(true);
 
obj:=pointer(1);
 
TP1.execute(myobj.myproc1,pointer(obj));
 
obj:=pointer(2);
 
TP1.execute(myobj.myproc2,pointer(obj));
 
TP1.setCounter() ;
 
TP1.wait(INFINITE);
 
readln;
 
TP1.free;
 
TP.Terminate;
 
TP.Free;
 
end.
 
 
 
Let us look at the first line...
 
uses
 
{$IFDEF Delphi}
 
cmem,
 
{$ENDIF}
 
cmem is required for Delphi to use TBB memory manager (from Intel) ,
this will allow delphi memory manager to scale linearely...
 
Note: FPC doesn't need cmem, cause it scales linearely with threads...
 
ThreadPool: is our threadpool unit ..
 
syncobjs: contains all the sychronizations stuff like CriticalSections,
Events etc..
 
After that we have the following lines:
 
type
 
TMyThread = class (TThreadPoolThread)
 
//procedure ProcessRequest(obj: Pointer); override;
 
procedure MyProc1(obj: Pointer);
 
procedure MyProc2(obj: Pointer);
 
end;
 
We declare a TMyThread that ineherit from TThreadPoolThread, and we
declare our two methods MyProc1 and MyProc2 that we want to be executed
by our threadpool's worker threads. Each method has an obj as a paramater.
 
In the main body we create a TMyThread object like this:
 
myobj:=TMyThread.create;
 
and after that we create a TThreadPool object with 4 workers threads
like this:
 
TP := TThreadPool.Create(4, TMyThread); // 4 workers threads.
 
After that you create ThreadPoolC object so that you can distribute your
jobs to the ThreadPool by writing this:
tp1:=TP.CreateThreadPoolC(true);
 
If you pass true to CreateThreadPoolC() , wait() will wait for all the
jobs to finish, if you pass false to CreateThreadPoolC(), wait() will
not wait for the jobs to finish.
 
After that we distribute to our worker threads the methods to be
executed , we do it by calling the Threadpool's execute() method and we
pass it myobj.myproc1 and myobj.myproc2 with there parameters:.
After that you have to call setCounter() and wait() to wait for all the
jobs..
 
TP.1.setCounter();
 
TP1.wait(INFINITE);
You have to call setCounter() , it is mandatory, the first parameter of
wait() is the time to wait in milliseconds, if you set it to INFINITE,
it will wait for the jobs to finish.
 
After that you have to free TP1 and TP objects.
 
As you see, Threadpool (and threadpool with priority) is very easy to use...
 
Let's look now at an example of a Threadpool with priority:.
 
program test;
 
 
 
uses
 
{$IFDEF Delphi}
 
cmem,
 
{$ENDIF}
 
PThreadPool,sysutils,syncobjs;
 
{$I defines.inc}
 
type
 
TMyThread = class (TPThreadPoolThread)
 
//procedure ProcessRequest(obj: Pointer); override;
 
procedure MyProc1(obj: Pointer);
 
procedure MyProc2(obj: Pointer);
 
end;
 
 
 
var
 
myobj:TMyThread;
 
TP: TPThreadPool;
 
obj:pointer;
 
cs:TCriticalSection;
 
tp1:TPThreadPoolC;
 
procedure TMyThread.MyProc1(obj: Pointer);
 
begin
 
cs.enter;
 
writeln('This is MyProc1 with parameter: ',integer(obj));
 
cs.leave;
 
end;
 
procedure TMyThread.MyProc2(obj: Pointer);
 
begin
 
cs.enter;
 
writeln('This is MyProc2 with parameter: ',integer(obj));
 
cs.leave;
 
end;
 
begin
 
myobj:=TMyThread.create;
 
cs:=TCriticalSection.create;
 
TP := TPThreadPool.Create(4,TMyThread, 20); // 4 workers threads and
2^20 items for each queue.
 
tp1:=TP.CreateThreadPoolC(true);
 
obj:=pointer(1);
 
TP1.execute(myobj.myproc1,pointer(obj),NORMAL_PRIORITY);
 
obj:=pointer(2);
 
TP1.execute(myobj.myproc2,pointer(obj),NORMAL_PRIORITY);
 
TP1.setCounter();
 
TP1.wait(INIFINITE);
 
readln;
 
TP.Terminate;
 
TP.Free;
 
end.
 
 
 
As you have noticed, this is almost the same as threadpool..
 
You use PThreadPool - P for priority - rather than Threadpool
 
TPThreadPoolThread rather than TThreadPoolThread
 
TPThreadPoolC rather than TThreadPoolC
 
TPThreadPool.Create rather than TThreadPool.Create
 
and as you have noticed in
TP.execute(myobj.myproc1,pointer(obj),NORMAL_PRIORITY) we are using
priorities.
 
You can give the following priorities to jobs:
 
LOW_PRIORITY
NORMAL_PRIORITY
HIGH_PRIORITY
 
 
 
That's all.
 
You can download threadpool (and threadpool with priority) from:
 
https://sites.google.com/site/aminer68/
 
Sincerely,
Amine Moulay Ramdane.
Ramine <ramine@1.1>: May 25 11:37AM -0700

Hello,
 
 
My efficient Threadpool engine with priorities was updated to version
2.1, i have changed the concurrent FIFO queue of my efficient Threadpool
engine with priorities, now the concurrent FIFO queue is waitfree on the
push() and lockfree on the pop(), so it's really fast, and i have also
changed the algorithm of my efficient Threadpool engine and now i have
tested it thoroughly and i think that it's a stable and a correct
algorithm and it's fast, i have also updated the HTML tutorial inside
the zipfile, please look inside the tutorial to learn how to use my
efficient Threadpool engine.
 
I have also updated my Threadpool engine to version 2.1..
 
 
You can download my efficient Threadpool engine with priorities version
2.1 from:
 
https://sites.google.com/site/aminer68/threadpool-with-priorities
 
 
And you can download my Threadpool engine version 2.1 from:
 
https://sites.google.com/site/aminer68/threadpool
 
 
Thank you,
Amine Moulay Ramdane.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.programming.threads+unsubscribe@googlegroups.com.

No comments: