Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  demo.g   Sprache: unbekannt

 
#############################################################################
#
# The code in this file should run in the HPC-GAP version
#
#############################################################################

ReadGapRoot("demo/threads.g");

# "Hello, World" from a thread example

t:=CreateThread( function() Print("Hello, Multithreaded World!\n");end );
WaitThread(t);

CurrentThread();

# multithreaded "Hello, World" example
hello:=function(n)
Sleep(n mod 3);
Print("Hello World, thread ", n, " with id ", CurrentThread(), " is here\n");
end;
threads:=List( [1..10], i -> CreateThread( hello, i ) );
Perform( threads, WaitThread );

# Global variables example
counter:=0;
nrthreads:=10;
l:=[];
ShareObj(l);;
w:=AtomicList(nrthreads);
hello:=function(n)
local t;
Sleep(n mod 3);
t:=counter;
counter:=counter+1;
Print("Thread ", n, " : ", t , " + 1 = ", counter, " \n");
w[n]:=counter;
atomic readwrite l do
    l[n]:=counter;
od;
end;
threads:=List( [1..nrthreads], i -> CreateThread( hello, i ) );
Perform( threads, WaitThread );
counter;
w;
r:=FromAtomicList(w);
atomic readwrite l do
    ADOPT(l); 
od;    
Print(r,"\n",l,"\n");
Print("Global variables test : ", r=l, "\n");

# Example 1. Simple operations channels with no threads
ch1:=CreateChannel();   
ch2:=CreateChannel();
SendChannel(ch1,6);
SendChannel(ch1,7);
SendChannel( ch2, ReceiveChannel(ch1)*ReceiveChannel(ch1));
ReceiveChannel(ch2);

Print("Passed example 1\n");

# Example 2. Sending to channel list elements in a loop inside a thread
ch:=CreateChannel();
n:=10000;
f:=function() local i; for i in [1..n] do SendChannel(ch,i); od; end;
CreateThread(f);
l:=List([1..n],i->ReceiveChannel(ch));;
l=[1..n];

Print("Passed example 2\n");

# Example 3. Two threads, each with own input and output channels
chin1:=CreateChannel();
chin2:=CreateChannel();
chout1:=CreateChannel();
chout2:=CreateChannel();
mult1:=function() SendChannel( chout1, ReceiveChannel(chin1)*ReceiveChannel(chin1)); end;
mult2:=function() SendChannel( chout2, ReceiveChannel(chin2)*ReceiveChannel(chin2)); end;
CreateThread(mult1);
CreateThread(mult2);
SendChannel(chin1,2);
SendChannel(chin1,3);
SendChannel(chin2,4);
SendChannel(chin2,5);
ReceiveChannel(chout1);
ReceiveChannel(chout2);

Print("Passed example 3\n");

# Example 4. Sending objects to a thread and receiving them back
ChannelTest:=function( obj )
local chin, chout, r, thread;
chin:=CreateChannel();
chout:=CreateChannel();
thread := CreateThread( function() SendChannel(chout, ReceiveChannel(chin) ); end ); 
SendChannel( chin, obj );
r:=ReceiveChannel( chout );
WaitThread( thread );
return r=obj;
end;

Print("Starting ChannelTests ... \n");
ChannelTest(1);
ChannelTest(E(4)); 
ChannelTest(Integers);
ChannelTest(DihedralGroup(1000));
ChannelTest(GAPInfo);            
ChannelTest(2^160000);
ChannelTest(Factorial);
ChannelTest(GlobalRandomSource);
ChannelTest("bla");  

Print("Performing ChannelTest in a loop ... ");
for i in [1..10000] do r:=ChannelTest(i); od; # time;
Print("done\n");

Print("Passed example 4\n");

# Example 5. A function to multiply objects in a thread
MultiplyInThread := function(a,b)
local chin, chout, thread, r;
chin:=CreateChannel();
chout:=CreateChannel();
SendChannel( chin, a );
SendChannel( chin, b );
thread := CreateThread( function() SendChannel(chout, ReceiveChannel(chin)*ReceiveChannel(chin) ); end ); 
r:=ReceiveChannel( chout );
WaitThread( thread );
return r;
end;
MultiplyInThread(6,7);

Print("Passed example 5\n");

# Example 6. Usage of CallFuncListThread and FinaliseThread
chin:=CreateChannel();
chout:=CreateChannel();
r:=CallFuncListThread( function(s) return s*s; end, [ 10 ], chin, chout);
# r:=CallFuncListThread( s -> Factorial(s), [ 10 ], chin, chout);
# The line below causes GAP to run forever
# r:=CallFuncListThread( s -> Size(SmallGroup(s)), [[8,3]], chin, chout);
FinaliseThread( r, chin, chout );

Print("Passed example 6\n");

# Example 7. Recursive computation of Fibonacci(n) with two threads on top.
fib_recursive := function(n)
if n in [1, 2] then
  return 1;
else
  return fib_recursive(n-1) + fib_recursive(n-2);
fi;
end;

fib_threads_recursive:= function(n)
local chin1, chin2, chout1, chout2, thread1, thread2, r1, r2;
if n in [1, 2] then
  return 1;
else
  chin1:=CreateChannel();
  chin2:=CreateChannel();
  chout1:=CreateChannel();
  chout2:=CreateChannel();  
  thread1:= CallFuncListThread( fib_recursive, [ n-1 ], chin1, chout1 );
  thread2:= CallFuncListThread( fib_recursive, [ n-2 ], chin2, chout2 );
  r1 := FinaliseThread( thread1, chin1, chout1 );
  r2 := FinaliseThread( thread2, chin2, chout2 );
 return r1+r2; 
fi;
end; 
fib_threads_recursive(6);

Print("Passed example 7\n");

# Example 8. Recursive computation of Fibonacci(n) creating two subthreads 
# on each step (good to exhaust resources and get segfaults)
fib_threads:= function(n)
local chin1, chin2, chout1, chout2, thread1, thread2, r1, r2;
if n in [1, 2] then
  return 1;
else
  chin1:=CreateChannel();
  chin2:=CreateChannel();
  chout1:=CreateChannel();
  chout2:=CreateChannel();  
  thread1:= CallFuncListThread( fib_threads, [ n-1 ], chin1, chout1 );
  thread2:= CallFuncListThread( fib_threads, [ n-2 ], chin2, chout2 );
  r1 := FinaliseThread( thread1, chin1, chout1 );
  r2 := FinaliseThread( thread2, chin2, chout2 );
  return r1+r2; 
fi;
end; 
fib_threads(6);

Print("Passed example 8\n");

ReadGapRoot("demo/atomic.g");
ReadGapRoot("demo/migrate.g");
ReadGapRoot("demo/fibtasks.g");


# Example 9. Compare standard, Fibonacci and threaded Fibonacci multiplication
ReadGapRoot("demo/karatsuba.g");
x:=Indeterminate(Rationals,"x");
nr:=IndeterminateNumberOfLaurentPolynomial(x);
fam:=FamilyObj(1);;
l:=[-4..5];
deg:=5000;
KARATSUBA_CUTOFF:=150; # quasi-optimal value for one main and two subthreads
f:=LaurentPolynomialByCoefficients( fam, List([1..deg],i->l[(i mod 10) + 1]), 0, 1 );;
g:=LaurentPolynomialByCoefficients( fam, List([1..deg],i->l[((i+5) mod 10) + 1]), 0, 1 );;
Print("Testing standard multiplication of polynomials ... ");
t1:=f*g;;
Print("done\n");
Print("Testing Karatsuba multiplication of polynomials ... ");
t2:=KaratsubaPolynomialMultiplication(f,g);; 
Print("done\n");
Print("Testing Karatsuba multiplication of polynomials in threads ... ");
t3:=KaratsubaPolynomialMultiplicationThreaded(f,g);; 
Print("done\n");
t1=t2; t1=t3; # this causes crash 

Print("Passed example 9\n");

# Example 10. Barriers
# This example works:
Print("Barrier test 1 \n");
bar:=CreateBarrier();
StartBarrier( bar, 3 );
t:=[];
for i in [1..3] do
    t[i]:=CreateThread( 
             function(i) 
             local t, s; 
             t:=NanosecondsSinceEpoch();
             s := Concatenation("Thread ", String(i), " started at ", 
                    String(t*1.E-9), "\n");
             Print( s );
             Sleep(i); 
             WaitBarrier(bar); 
             t:=NanosecondsSinceEpoch();
             s := Concatenation("Thread ", String(i), " stopped at ", 
                    String(t*1.E-9), "\n");
             Print( s );
             end, 
             i );
od;
for i in [1..3] do WaitThread(t[i]); od;

# And this not:
Print("Barrier test 2 \n");
m:=MakeImmutable(List([1..10],i->List([1..10],j->10*(i-1)+j)));
s:=AtomicList(10);
bar:=CreateBarrier();
StartBarrier( bar, Length(m)+1 );
t:=[];
for i in [1..Length(m)] do
    t[i]:=CreateThread( function(i) s[i]:=Sum( List(m[i], Factorial ) ); WaitBarrier(bar); end, i );
od;
WaitBarrier(bar);
x1:=Sum(FromAtomicList(s));
x2:=Sum(List([1..100],Factorial));
for i in [1..Length(t)] do WaitThread(t[i]); od;
Print(x1,"\n");
Print(x2,"\n");
Print( "Barrier test 2 ", x1=x2, "\n");

Print("Passed example 10\n");

Print("=======================\nChecking access.tst ...\n");
tst := Filename( DirectoriesLibrary("tst"), "access.tst" );;
Test(tst);
Print("Completed access.tst!!!\n");

Print("*** END OF THE TEST ***\n");


[ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge