Enrico Schwass
2004-Oct-16 05:39 UTC
[Ruby-de-talk] n Prozesse starten - Computer Language Shootout
Hallo zusammen
Der gestern erw?hnte Test kurz genauer beschrieben
----------------------------------------schnipp-------------
For this test, each program should be implemented to do the same thing.
This test measures the speed of process (or thread) instantiation.
In theory, a CO (Concurrency Oriented) language will have superior
performance in this test. Let''s see if our theory holds up!
After the process is created, it should wait on/for an event of some kind.
The actual event does not matter -- it could be a condition variable, a
semaphore,
an e-mail, whatever. The important thing is that it is an individual
event, so that this
particular process can be told to continue its execution without
disturbing the
other processes in this test.
The test program should take one argument, N, which is the number
of processes to create.
The correct output, after all processes have been created, is N.
-----------------------------und durch Babelfish gejagt-----------------
F?r diesen Test sollte jedes Programm implementiert werden, um die gleiche
Sache zu tun. Dieser Test mi?t die Geschwindigkeit der
Proze?-Instantiation.
In der Theorie hat eine Co (die Parallelit?t orientiert)-Sprache ?berlegene
Leistung in diesem Test. La? uns sehen, ob unsere Theorie h?lt! Nachdem der
Proze? verursacht ist, sollte er warten auf einen Fall irgendeiner Art. Der
tats?chliche Fall macht nicht aus -- es k?nnte eine Bedingungvariable, ein
Semaphor, eine E-mail sein, was auch immer. Die wichtige Sache ist, da? es
ein einzelner Fall ist, damit diesem bestimmten Proze? erkl?rt werden kann,
seine Durchf?hrung fortzusetzen, ohne die anderen Prozesse in diesem Test
zu st?ren. Das Testprogramm sollte ein Argument, N nehmen, das die Zahl
der zu verursachenden Prozesse ist. Der korrekte Ausgang, nachdem alle
Prozesse verursacht worden sind, ist N.
--------------------------------schnapp--------------------------------------------
Bis auf ein paar Nachbesserungen sind diese Babelfish-?bersetzungen
verflucht gut. Was ich mir als m?gliche L?sung vorstelle w?re folgendes
-----------------------------------------------------------------------------------
threads = []
# Anzahl der Threads als Argument
n = ARGV[0].to_i
# Condition variable
check = 0
for t in 1..n
threads << Thread.new(t) { |my_t|
puts "Running " + my_t.to_s
loop do
break if my_t == check
end
puts "Finishing " + my_t.to_s
}
end
# Beende zuf?llig gew?hlte Threads
loop {
# ohne die 0
check = rand(n+1)
# einer l?uft immer
break if Thread.list.length == 1
}
puts "All threads finished"
---------------------------------------------------------------------------------
Nat?rlich sollte man f?r den Benchmark die Kommentare und
puts-Anweisungen herausnehmen. Es reicht, zur Demonstration
lediglich einen Thread zu beenden.
Bis die Tage
Enno
PS: Hat schon mal einer mit SOAP herumgespielt?? Ich h?tte gern einen
Server, der
auf allen Rechnern im Netz meine TODO-Listen abgleicht. Ist zwar mit
Kanonen auf
Spatzen geschossen, aber mir f?llt nichts anderes ein um mich dem Thema
Web-Services
zu n?hern :)
Enrico Schwass
2004-Oct-17 05:44 UTC
[Ruby-de-talk] n Prozesse starten - Computer Language Shootout
Moin> Hallo zusammen > > Der gestern erw?hnte Test kurz genauer beschrieben > ...Vielleicht h?tte ich auch genauer lesen sollen.> Der korrekte Ausgang, nachdem alle > Prozesse verursacht worden sind, ist N.Das fehlte noch.> > Nat?rlich sollte man f?r den Benchmark die Kommentare und > puts-Anweisungen herausnehmen. Es reicht, zur Demonstration > lediglich einen Thread zu beenden.Apropos Benchmark. Probiert hatte ich es erst mit 5 Threads. Jetzt mit 100. Das dauert 55 Sekunden auf meiner Kiste. 128000 Threads sind in der Aufgabenstellung gefordert. Das wird inakzeptabel mit Ruby. Ein kleiner Bytecompilerlauf mit Cardinal und Parrot und das ganze meldet sich ohne nennenswerte Verz?gerungen zur?ck. Aber eben auch ohne Ergebnis. Das ist noch sehr Alpha :) Weiterhin k?nnte man auch die Mutex-Klasse benutzen. Hab ich bisher vermieden. Aber ob das noch ein paar Prozent bringt. Bis die Tage Enno
Michael Neumann
2004-Oct-17 19:01 UTC
[Ruby-de-talk] n Prozesse starten - Computer Language Shootout
On Sat, Oct 16, 2004 at 11:39:56AM +0200, Enrico Schwass wrote:> threads = [] > > # Anzahl der Threads als Argument > > n = ARGV[0].to_i > > # Condition variable > > check = 0 > > for t in 1..n > threads << Thread.new(t) { |my_t| > puts "Running " + my_t.to_s > loop do > break if my_t == check > end > puts "Finishing " + my_t.to_s > } > end > > # Beende zuf?llig gew?hlte Threads > > loop { > > # ohne die 0 > check = rand(n+1) > > # einer l?uft immer > break if Thread.list.length == 1 > } > > puts "All threads finished"Weisst du warum das so langsam ist? Du solltest keine Zufallszahlen verwenden. Denn, dann kannst du lange warten bis alle beendet sind. Ausserdem, es l?uft ja immer nur ein Thread, und es kann gut sein, das du "check" mehrmals zuweist, bevor ?berhaupt ein anderer Thread an die Reihe kommt um zu pr?fen ob er sich nun beenden soll. Ich habe das ganze mal mit Mutexes geschrieben: require ''thread'' n = ARGV[0].to_i (1..n).map { mutex = Mutex.new mutex.lock Thread.new(mutex) {|m| m.synchronize {} } mutex }.each {|m| m.unlock } print n Oder eben noch k?rzer und schneller: n = ARGV[0].to_i (1..n).map { Thread.new { Thread.stop } }.each {|t| t.wakeup}.each {|t| t.join} print n Das erste Beispiel dauert bei mir bei 1000 Threads so ca. 2 Sekunden. Das zweite nur 1,5. Und wenn du das t.join direkt hinter t.wakeup setzt, dann ist es nochmals doppelt so schnell. Nur steigt die Laufzeit leider nicht linear an. D.h. bei 2000 Threads ist die Laufzeit schon 6-mal so lange.> PS: Hat schon mal einer mit SOAP herumgespielt?? Ich h?tte gern einen > Server, der > auf allen Rechnern im Netz meine TODO-Listen abgleicht. Ist zwar mit > Kanonen auf > Spatzen geschossen, aber mir f?llt nichts anderes ein um mich dem Thema > Web-Services > zu n?hern :)Kannst auch XML-RPC verwenden. Ist vielleicht f?r den Anfang noch leichter. Gr?sse, Michael
Enrico Schwass
2004-Oct-18 04:24 UTC
[Ruby-de-talk] Re: n Prozesse starten - Computer Language Shootout
Hallo Michael
>Weisst du warum das so langsam ist? Du solltest keine Zufallszahlen
>verwenden. Denn, dann kannst du lange warten bis alle beendet sind.
:) Beim Benchmark habe ich nat?rlich diese Zeilen auskommentiert.
>Ausserdem, es l?uft ja immer nur ein Thread, und es kann gut sein, das
Hmm... das w?rde ja der Intention von threads widersprechen. Ach du
meinst weil der Prozessor immer nur jeweils einen in der Zeitscheibe
abarbeitet.
>du "check" mehrmals zuweist, bevor ?berhaupt ein anderer Thread
an die
>Reihe kommt um zu pr?fen ob er sich nun beenden soll.
Ja, stimmt. Zum Benchmark sah das Programm auch eher so aus. Das
erf?llt die Aufgabenstellung ?ndert aber nat?rlich nichts an der schlechten
Performance.
> threads = []
>
> # Anzahl der Threads als Argument
>
> n = ARGV[0].to_i
>
> # Condition variable
>
> check = 0
>
> for t in 1..n
> threads << Thread.new(t) { |my_t|
> loop do
> break if my_t == check
> end
> }
> end
> check = 1 # beende zur Demonstration den ersten Thread
> # bei Programmende enden alle Threads
> Ich habe das ganze mal mit Mutexes geschrieben:
Die Idee hatte ich kurz darauf. Versprach mir allerdings keinen
Geschwindigkeitsvorteil.
Wenn du aber berichtest, das du 1000 Threads in 2 Sekunden laufen l?sst
ist das eine ganz
erhebliche Steigerung. Interessant.
>Das erste Beispiel dauert bei mir bei 1000 Threads so ca. 2 Sekunden.
>Das zweite nur 1,5. Und wenn du das t.join direkt hinter t.wakeup setzt,
>dann ist es nochmals doppelt so schnell.
Da die Threads durchaus mit dem Hauptprogramm beendet werden k?nnen,
hatte ich auf das join verzichtet. Ich schau mir deine Beispiele in
aller Ruhe an und melde
mich dann wieder.
Bis die Tage
Enno
Michael Neumann
2004-Oct-18 04:53 UTC
[Ruby-de-talk] Re: n Prozesse starten - Computer Language Shootout
On Mon, Oct 18, 2004 at 10:24:51AM +0200, Enrico Schwass wrote:> Hallo Michael > > >Weisst du warum das so langsam ist? Du solltest keine Zufallszahlen > >verwenden. Denn, dann kannst du lange warten bis alle beendet sind. > > :) Beim Benchmark habe ich nat?rlich diese Zeilen auskommentiert. > > >Ausserdem, es l?uft ja immer nur ein Thread, und es kann gut sein, das > > Hmm... das w?rde ja der Intention von threads widersprechen. Ach du > meinst weil der Prozessor immer nur jeweils einen in der Zeitscheibe > abarbeitet.Ist aber so. Die laufen in Wirklichkeit nur quasi-parallel.> >du "check" mehrmals zuweist, bevor ?berhaupt ein anderer Thread an die > >Reihe kommt um zu pr?fen ob er sich nun beenden soll. > > Ja, stimmt. Zum Benchmark sah das Programm auch eher so aus. Das > erf?llt die Aufgabenstellung ?ndert aber nat?rlich nichts an der schlechten > Performance. > > > threads = [] > > > > # Anzahl der Threads als Argument > > > > n = ARGV[0].to_i > > > > # Condition variable > > > > check = 0 > > > > for t in 1..n > > threads << Thread.new(t) { |my_t| > > loop do > > break if my_t == check > > end > > } > > end > > check = 1 # beende zur Demonstration den ersten Thread > > # bei Programmende enden alle Threads > > > Ich habe das ganze mal mit Mutexes geschrieben: > > Die Idee hatte ich kurz darauf. Versprach mir allerdings keinen > Geschwindigkeitsvorteil. > Wenn du aber berichtest, das du 1000 Threads in 2 Sekunden laufen l?sst > ist das eine ganz > erhebliche Steigerung. Interessant.Das liegt wohl daran, das meine Threads keine Anweisungen ausf?hren, und somit keine anderen Threads vor dem Ablaufen blockieren. Was du machst, nennt sich "busy-waiting", und das ist "teuer". Blockierte Threads werden gar nicht neu ge-scheduled, d.h. neben keine Zeit aus der Zeitscheibe weg.> >Das erste Beispiel dauert bei mir bei 1000 Threads so ca. 2 Sekunden. > >Das zweite nur 1,5. Und wenn du das t.join direkt hinter t.wakeup setzt, > >dann ist es nochmals doppelt so schnell. > > Da die Threads durchaus mit dem Hauptprogramm beendet werden k?nnen, > hatte ich auf das join verzichtet. Ich schau mir deine Beispiele in > aller Ruhe an und melde > mich dann wieder.Hm, die Aufgabenstellung von shootout ist dahingehen sehr undurchsichtig. Gr?sse, Michael