 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 28.11.2007, 15:16 Titel: "Kleiner" Thread-Benchmark? |
|
|
Ich hab mich darin versucht eine Aufgabe (Apfelmännchen zeichnen) auf 2 CPUs zu verteilen.
Das Apfelmännchen ist dafür geradezu prädesteniert. Einfach den Bildschirm aufteilen und in 2 threads berechnen.
So hab ichs auch gemacht! In stiller hoffnung das es fast doppelt so schnell berechnet ist. Ich besitze hier einen Intel Core2Duo mit 2 physischen Prozessoreinheiten auf der Die. Also KEIN Hypterthreading oder sowas...
Um den unterschied zu testen wie es sich zu einem Thread verhält habe ich folgendes kleines Progrämmchen abgeändert:
Code: |
DIM SHARED threadsync AS INTEGER
DIM SHARED thread1handle AS INTEGER
DIM SHARED thread2handle AS INTEGER
type rng
ystart as integer
ymax as integer
end type
Screen 21, 32, 1, 0
Sub Main (rng1 as rng ptr)
Dim X As Integer
Dim Y As Integer
Dim Count As Integer
Dim Size As Double
Dim R As Double
Dim I As Double
Dim RTmp As Double
Dim Rs As Double
Dim Iss As Double
For Y = rng1->ystart to rng1->ymax
For X = 0 to 1280
Count = 1024
Size = 0
R = 0
I = 0
While Size < 4 And Count > 0
RTmp = R
Rs = R * R
Iss = I * I
R = (Rs - Iss) + (X - 720) / 320
I = (2 * (RTmp * I)) + (Y - 512) / 320
Size = Rs + Iss
Count = Count - 1
Wend
MUTEXLOCK threadsync
Pset (X, Y), RGB(Count ,count,count)
MUTEXUNLOCK threadsync
Next
Next
End Sub
dim t1 as double
dim t2 as double
dim its1 as double
dim its2 as double
t1 = timer
threadsync = MUTEXCREATE
dim rng0 as rng
dim rng1 as rng
dim rng2 as rng
rng0.ystart =0
rng0.ymax = 1024
rng1.ystart =0
rng1.ymax = 512
rng2.ystart =512
rng2.ymax = 1024
thread1handle = THREADCREATE(@Main, @rng0)
THREADWAIT(thread1handle)
t2 = timer
its1 = (1280* 1024) / (t2 - t1)
sleep 1000
t1 = timer
thread1handle = THREADCREATE(@Main, @rng1)
thread2handle = THREADCREATE(@Main, @rng2)
THREADWAIT(thread1handle)
THREADWAIT(thread2handle)
t2 = timer
its2 = (1280* 1024) / (t2 - t1)
locate 1,1:Print "Single Thread (its/sec): " & its1
locate 2,1:Print "Dual Thread (its/sec) : " & its2
locate 3,1:Print "Acceleration : " & (int((its1/its2)*100) /100) & "X"
sleep
|
Falls ihr das Programm mit einer anderen auflösung laufen lassen wollt müsst ihr allerdings an mehreren stellen die auflösungsmaxima ändern.
Nun ist mir aber Aufgefallen das es nicht zu einer Beschleunigung kommt, sonder es verlangsamt sich fast ums doppelte. (Wert bei "Acceleration" sollte bei einer beschleunigung durch die thread aufteilung größer > 1 sein)
Kann sich das einer erklären warum es eher ausbremst als beschleundigt? |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 28.11.2007, 16:49 Titel: Auch ganz witzig... |
|
|
Code: |
DIM SHARED threadsync AS INTEGER
declare sub th1(pos1 as integer)
dim i as integer
cls
threadsync = MUTEXCREATE
for i = 1 to 8
threadcreate( @th1,i)
next
sleep
sub th1(pos1 as integer)
dim t1 as double
dim t2 as double
dim i as double
t1 = timer
DO
t2 = timer
if t2 >= t1 +1 then
MUTEXLOCK threadsync
locate pos1,1:print Pos1 & " I/s: " & i & " "
MUTEXUNLOCK threadsync
t1 = timer
i = 0
end if
i = i +1
'sleep 1
loop
end sub
|
Es misst die "Iterationen" die ein Thread in einer Sekunde schaffen kann.
Ich glaube, ein zufallsgenerator könnte keine schöneren Zahlen liefern
->Bin der Erfinder des "Threadrauschends"
nimmt man "sleep 1" in den thread mit hinein, beschränkt sich jede ausgabe des jeweiligen threads auf genau 65 I/s
Wie schauts bei euch aus? |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 28.11.2007, 18:17 Titel: |
|
|
Mit Sleep 1 -> 65.
Ansonsten zwischen 17000 und 25000. _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 28.11.2007, 19:46 Titel: |
|
|
Hi,
mit dem 2.Prog komme ich garnicht zurecht??
Das erste Prog habe ich mal etwas geändert, Screen 21 ist etwas zu groß für meine Graka (dafür mag ich es bunter )
Code: | Dim Shared threadsync As Any Ptr
Dim Shared thread1handle As Any Ptr
Dim Shared thread2handle As Any Ptr
Type rng
ystart As Integer
ymax As Integer
End Type
Screen 19, 8
Sub Main (ByRef yrng As rng)
Dim As Integer X, Y, Count
Dim As Single Size, R, I, RTmp, Rs, Iss
For Y = yrng.ystart To yrng.ymax
For X = 0 To 800-1
Count = 600
Size = 0
R = 0
I = 0
While Size < 4 And Count > 0
RTmp = R
Rs = R * R
Iss = I * I
R = (Rs - Iss) + (X - 600) / 320
I = (2 * (RTmp * I)) + (Y - 300) / 320
Size = Rs + Iss
Count = Count - 1
Wend
MutexLock threadsync
PSet (X, Y), (count Mod 256)
MutexUnLock threadsync
Next
Next
End Sub
Dim As Double t1, t2, its1, its2
Dim As rng rng0, rng1, rng2
threadsync = MutexCreate
rng0.ystart = 0
rng0.ymax = 600-1
t1 = Timer
'thread1handle = ThreadCreate(Cast(Any Ptr,@Main), @rng0)
'ThreadWait(thread1handle)
Main rng0
t2 = Timer
its1 = (800* 600) / (t2 - t1)
Sleep 1000
Cls
rng1.ystart = 0
rng1.ymax = 300-1
rng2.ystart = 300
rng2.ymax = 600-1
t1 = Timer
thread1handle = ThreadCreate(Cast(Any Ptr,@Main), @rng1)
thread2handle = ThreadCreate(Cast(Any Ptr,@Main), @rng2)
ThreadWait(thread1handle)
ThreadWait(thread2handle)
t2 = Timer
its2 = (800* 600) / (t2 - t1)
MutexDestroy(threadsync)
Locate 1,1:Print "SINGLE Thread (pixel/sec): " & its1
Locate 2,1:Print "Dual Thread (pixel/sec) : " & its2
Locate 3,1:Print "Acceleration : " & (Int((its2/its1)*100) /100) & "fach"
Sleep | Alles was da bremst ist Code: | MutexLock threadsync
PSet (X, Y), (count Mod 256)
MutexUnLock threadsync
| selbst wenn du mit einem DuoProz arbeitest muss der Grafikspeicherzugiff freigegeben sein sonst wartet der Thread. _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 29.11.2007, 00:11 Titel: |
|
|
das bremsende hier ist der ineffiziente grafikzugriff.. am besten einfach erst berechnen und dann entweder in großen blöcken oder komplett alles auf einmal zeichnen wenns fertig gerechnet ist. Ansonsten ist das verhältnis rechnen zu grafik (die nicht parallel gemacht werden kann) nicht groß genug als dass man da was merken würde. _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
ThePuppetMaster

Anmeldungsdatum: 18.02.2007 Beiträge: 1839 Wohnort: [JN58JR]
|
Verfasst am: 29.11.2007, 06:58 Titel: |
|
|
öm .... euch ist klar, das die Erstellung von 2 Threads nicht zwangsläufig auf 2 CPU-Kerne verteilt wird?
Dies ist Betriebssystemabhängig! ... Unter Windows gibt es hierfür einen eigenen API Bereich, der es ermöglicht Threads einem Prozessorkern zuzuweisen (Was allerdings ausdrücklich NICHT zu empfehlen ist).
MfG
TPM _________________ [ WebFBC ][ OPS ][ ToOFlo ][ Wiemann.TV ] |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 29.11.2007, 12:50 Titel: |
|
|
Hi,
ich habe mal die SUB Main so geändert, dass nicht nach jeder Pixelberechnung Mutexlock und Mutexunlock ausgeführt wird.
In einem Image wird jedesmal die ganze Zeile berechnet und erst danach in den Grafikspeicher geputet.
Code: | Sub Main (ByRef yrng As rng)
Dim As Integer X, Y, Count
Dim As Single Size, R, I, RTmp, Rs, Iss
Dim As Byte Ptr img = ImageCreate(800,1) ' eine Zeile
For Y = yrng.ystart To yrng.ymax
For X = 32 To 832-1'Trick statt img[X+32]
Count = 600
Size = 0
R = 0
I = 0
While Size < 4 And Count > 0
RTmp = R
Rs = R * R
Iss = I * I
R = Rs - Iss + ((X - 650) / 320)
I = (2 * RTmp * I) + ((Y - 300) / 320)
Size = Rs + Iss
Count -= 1
Wend
img[X]= (count Mod 256)
Next
MutexLock threadsync
Put (0,Y), img, pset
MutexUnlock threadsync
Next
ImageDestroy img
End Sub |
Damit wird selbst auf meiner SingelCPU deutlich, dass 2 Threads etwas (sehr geringfügig ~2%) schneller sind.
Hier das ganze Prog: ( http://www.freebasic-portal.de/index.php?s=fbporticula&mode=show&id=305 ) _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
atari gesperrt
Anmeldungsdatum: 26.08.2007 Beiträge: 144
|
Verfasst am: 29.11.2007, 20:02 Titel: |
|
|
ich bezweifle das ihr die richtigen ansprechbefehle dafür genommen habt.
die progammhersteller(cad/photo usw) tun sich sehr schwer dieses in der software zu verwirklichen. weil nur der rechenprozess berücksichtigt wird und die grafikdarstellung alles wieder kaputt macht.
zur zeit weiss ich nicht welches kaufbare programm tatsächlich die befehle anspricht ohne den user anzumogeln, denn er hat keine normal möglichkeit ausser er zerpflückt den asm-code. |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 29.11.2007, 20:07 Titel: |
|
|
Was bitte willst du uns sagen? oO
@volta:
Auf einer SingleCore-CPU mit 2 Threads schneller? Wie geht das denn?
Könnte ich mir vllt. durch Hintergrundprozesse erklären, rein theoretisch müsste die "DualThread"-Variante jedoch etwas langsamer sein. _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
Stormy

Anmeldungsdatum: 10.09.2004 Beiträge: 567 Wohnort: Sachsen - wo die schönen Frauen wachsen ;)
|
Verfasst am: 29.11.2007, 23:43 Titel: |
|
|
@Mao: Das geht deswegen schneller, weil die CPU keinen langsamen Kontextswitch (Register retten, etc.) zwischen Prozessen machen muss, sondern nur innerhalb des Prozesses mit den zwei Threads wechseln muss.
Edit: Ich seh grad. Es ging ja nicht darum...hab dein Posting nicht ganz genau durchgelesen. Es könnte aber sein, dass durch die Thread-Implementierung wohl mehr CPU-Zeit für den Prozess vom Betriebssystem gegönnt wird. _________________ +++ QB-City +++ Die virtuelle Stadt für jeden Freelancer - Join the community!
Projekte: QB-City,MysticWorld (RPG), 2D-OpenGL-Tutorial |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 30.11.2007, 00:41 Titel: |
|
|
ich würde auf "während die cpu bei einem thread auf die grafik warten muss kann sie bei zwei threads solang in dem anderen thread was weiterrechnen" tippen  _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 30.11.2007, 15:38 Titel: |
|
|
Hi,
ich habe leider nur geringe Kenntnisse wie Windows die Threads verwaltet.
Ich habe den Zeitvorteil von 2 Threads auf einer Singelcpu genau wie MisterD gedeutet.
War aber ein Irtum
Wenn ich diesen Teil auskommentiere Code: | ' MutexLock threadsync
' Put (0,Y), img, pset
' MutexUnlock threadsync | werden keine weiteren Grafikbefehle ausgeführt und an dem Geschwindigkeitsvorteil der 2 Threads ändert sich nichts.
Nächster Versuch mit 4 Threads ~5% schneller als der Singelthread?
Aber warum? _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 30.11.2007, 15:54 Titel: |
|
|
@Stormy:
Hm, Thread und Prozess, das ist auf Hardware-Ebene einerlei. Jeder Thread erwartet ja wie jeder Prozess auch, später genau dort weitermachen zu können, wie als er aufgehört hatte.
Bzw. er hat ja "quasi" keine Pause, von alldem bekommt er ja nix mit.
Wundert mich trotzdem.  _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
MisterD

Anmeldungsdatum: 10.09.2004 Beiträge: 3071 Wohnort: bei Darmstadt
|
Verfasst am: 30.11.2007, 17:03 Titel: |
|
|
könnte auch am pipelining liegen volta was fürn prozessor hast du denn? _________________ "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
Edsger W. Dijkstra |
|
Nach oben |
|
 |
Bimi
Anmeldungsdatum: 03.12.2007 Beiträge: 66
|
Verfasst am: 03.12.2007, 20:14 Titel: Re: "Kleiner" Thread-Benchmark? |
|
|
OneCypher hat Folgendes geschrieben: | Ich hab mich darin versucht eine Aufgabe (Apfelmännchen zeichnen) auf 2 CPUs zu verteilen.
Das Apfelmännchen ist dafür geradezu prädesteniert. Einfach den Bildschirm aufteilen und in 2 threads berechnen.
So hab ichs auch gemacht! In stiller hoffnung das es fast doppelt so schnell berechnet ist. Ich besitze hier einen Intel Core2Duo mit 2 physischen Prozessoreinheiten auf der Die. Also KEIN Hypterthreading oder sowas...
Nun ist mir aber Aufgefallen das es nicht zu einer Beschleunigung kommt, sonder es verlangsamt sich fast ums doppelte. (Wert bei "Acceleration" sollte bei einer beschleunigung durch die thread aufteilung größer > 1 sein)
Kann sich das einer erklären warum es eher ausbremst als beschleundigt? |
Ja, kann ich...
Zwei Prozessorkerne oder Prozessoren können sich wunderbar gegenseitig ausbremsen...
Vereinfacht ausgedrückt:
In jeder CPU steckt ein Stück Speicher, der sogenannte Cache. Er hat die Aufgabe zu verhindern das die CPU durch den für sie schneckenlangsamen Speicher ausgebremst wird. Die CPU weiß welche Daten sie gerade im Cache hat und bei welchen sie auf den Hauptspeicher zurückgreifen muss. Das funktioniert wunderbar - solange die CPU aleine ist. Kommt eine zweite CPU ins Spiel dann kann die erste CPU nicht davon ausgehen, das die Daten in ihrem Cache mit denen im Speicher noch übereinstimmen - sie könnten zwischenzeitlich durch die andere CPU geändert worden sein. Diese Prüfung ist nur dann notwendig, wenn beide CPU's im selben Speicherbereich unterwegs sind.
Laufen zwei Threads und nutzen diese bezüglich der Daten die gleiche Spreicherkachel, so muss die CPU vor einem Zugriffugriff überprüfen ob die Daten im Cache noch aktuell sind - und dazu muss sie die zweite CPU befragen ob diese vielleicht die Daten bereits geändert hat. Das hat nichts mit der Thread-Synchronisation zu tun, die muss der Entwickler nach wie vor selbst erledigen. Das Problem betrifft die CPU selbst.
Dieser Abgleich kostet Zeit! Würden diese beiden Threads auf einer CPU laufen, wären sie in der Summe schneller. Einfach ein Programm nehmen, in Threads aufteilen und dann hoffen das diese (im Idealfall) doppelt so schnell laufen, ist nicht. Damit eine Multithreaded Application von mehreren CPU-Kernen profitieren kann, müssen diese Treads explizit dafür designed sein.
Das bedeutet konkret:
Keine gemeinsamen Datenbereiche auf die häufig zugegriffen wird.
Soviel wie möglich mit dem Stack arbeiten - die sind stets getrennt
Datenstrukturen und Ressourcen so anlegen das auf Synchronisation nach Möglichkeit verzichtet werden kann. Wenn ist eine Datenstruktur habe über die viel abgewickelt wird und ich diese Synchronisieren muss, kann ich mir das Multithreading schenken.
Dein Proggi ist aber im Prinzip her MT-tauglich ... aber...
Miss mal dein Programm aus - 50% der Zeit bleibt in der Mutex hängen.
PSET ist schneckenlahm und ausgerechnet dieser Teil kann nicht paralelisiert werden... Außerdem: Der Anteil der Rechenzeit welche zusätzlich durch die Mutex verbraucht wird, ist im Gesamtkontext zu hoch. Während Thread A seinen Punkt zeichnet, wartet Thread B auf die Mutex....könnte aber in dieser Zeit rechnen. Thread A ist fertig und steht schneller wieder an der Mutex als Thread B zum Zeichnen braucht....
Die Lösung für deinen Fall ist eine Asymetrische Aufteilung:
Zwei Threads - einer rechnet, der andere zeichnet, kommunikation über einen FIFO-Buffer. Der (oder die) Rechenthread(s) schreiben ihre Ergebsnisse in entsprechende FiFo-Buffer und der Zeichenthread entnimmt dort die Resultate und zeichnet sie. Dafür würde sich eine U-Pipe eignen, die aber assynchron betrieben werden muss - sonst hast du das Problem gelich wieder....
mfg
Thomas |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 05.12.2007, 12:21 Titel: |
|
|
Tatsache ist, das ich mit dem proggi von Volta eine beschleunigung von 1,9fach hinbekomme .. das ist doch schon mal ne adresse
Werde mich in zukunft bemühen so wenig gemeinsame resourcen wie möglich die threads teilen zu lassen. Die sache ist halt nur die, das man als aussenstehender sogut wie nie weiss welche befehle dazu führen das ein thread wartet und welcher nicht. "Private" Datenbereiche innerhalb eines threads wären dafür wohl meistens ideal. Und am schluss dann die ausgabe dieser Datenbereiche.
Volta hat das schon ganz gut hinbekommen, so das erst eine ausgabe geschieht wenn die zeile fertig berechnet ist.
Der nächste größere schritt, um sich einer beschleunigung von 2 zu nähern, wäre dann wohl den kompletten bereich in einem privaten datenbereich zu schreiben und dann das komplette image am ende der berechnung ausgeben zu lassen.
Aber bin ja schon einen ganz guten schritt weiter danke an alle!! Dieser thread macht echt spaß mit euch!! |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 05.12.2007, 12:30 Titel: |
|
|
Grade noch mal neugierde halber noch was getestet was hier schon mal angesprochen wurde (allerdings mit voltas single-core cpu):
Meine CPU besitzt wie schon gesagt 2 kerne. Also dachte ich mir das man mit 2 threads die kerne am besten auslastet.
So habe ich mit voltas proggi 1,9 fache beschleundigung geschafft.
Erweitere ich das proggi allerdings so, dass ich nicht nur 2 threads starte sondern 4, erhalte ich tatsächlich eine beschleunigung von genau 2X !!!
Code: |
Dim Shared threadsync As Any Ptr
Dim Shared thread1handle As Any Ptr
Dim Shared thread2handle As Any Ptr
Dim Shared thread3handle As Any Ptr
Dim Shared thread4handle As Any Ptr
Type rng
ystart As Integer
ymax As Integer
End Type
Screen 19, 8
Sub Main (ByRef yrng As rng)
Dim As Integer X, Y, Count
Dim As Single Size, R, I, RTmp, Rs, Iss
Dim As Byte Ptr img = ImageCreate(800,1) ' eine Zeile
For Y = yrng.ystart To yrng.ymax
For X = 32 To 832-1'Trick statt img[X+32]
Count = 600
Size = 0
R = 0
I = 0
While Size < 4 And Count > 0
RTmp = R
Rs = R * R
Iss = I * I
R = Rs - Iss + ((X - 650) / 320)
I = (2 * RTmp * I) + ((Y - 300) / 320)
Size = Rs + Iss
Count -= 1
Wend
img[X]= (count Mod 256)
Next
MutexLock threadsync
Put (0,Y), img, pset
MutexUnlock threadsync
Next
ImageDestroy img
End Sub
Dim As Double t1, t2, its1, its2
Dim As rng rng0, rng1, rng2,rng3,rng4
threadsync = MutexCreate
rng0.ystart = 0
rng0.ymax = 600-1
t1 = Timer
thread1handle = ThreadCreate(Cast(Any Ptr,@Main), @rng0)
ThreadWait(thread1handle)
t2 = Timer
its1 = (800* 600) / (t2 - t1)
cls
Sleep 1000
'Cls
rng1.ystart = 0
rng1.ymax = 149
rng2.ystart = 150
rng2.ymax = 299
rng3.ystart = 300
rng3.ymax = 449
rng4.ystart = 450
rng4.ymax = 600
t1 = Timer
thread1handle = ThreadCreate(Cast(Any Ptr,@Main), @rng1)
thread2handle = ThreadCreate(Cast(Any Ptr,@Main), @rng2)
thread1handle = ThreadCreate(Cast(Any Ptr,@Main), @rng3)
thread2handle = ThreadCreate(Cast(Any Ptr,@Main), @rng4)
ThreadWait(thread1handle)
ThreadWait(thread2handle)
ThreadWait(thread3handle)
ThreadWait(thread4handle)
t2 = Timer
its2 = (800* 600) / (t2 - t1)
MutexDestroy(threadsync)
Locate 1,1:Print "SINGLE Thread (pixel/sec): " & its1
Locate 2,1:Print "Dual Thread (pixel/sec) : " & its2
Locate 3,1:Print "Acceleration : " & (Int((its2/its1)*100) /100) & "fach"
Sleep
|
Langsam werden threads für mich immer attraktiver  |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 05.12.2007, 13:47 Titel: |
|
|
Hi,
ja das ist der gleiche Quellcode bei dem ich (SingelCPU) ~5% Beschleunigung erreichte.
Übrigens geht dieser Zeitvorteil mit wachsender Threadanzahl wieder zu 0 (~ 10-12 Threads bei mir).
Ich vermute dieser Effekt hat nichts mit der verwendeten CPU (MisterD Vermutung: pipelining) zu tun, sondern wie
Stormy hat Folgendes geschrieben: | Es könnte aber sein, dass durch die Thread-Implementierung wohl mehr CPU-Zeit für den Prozess vom Betriebssystem gegönnt wird. |
Eine geringe Anzahl Threads kann von diesem Effekt profitieren, bei einer größeren Anzahl wird dies durch erstellen und verwalten dieser Threads wieder aufgehoben. _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 05.12.2007, 15:26 Titel: |
|
|
Also wenn du vermutest das es nichts mit dem prozessortyp zu tun hat, dann könnte man dies ja mit einem kleinen test ermitteln.
ich schreibe dafür mal ein kleines testprogramm.. |
|
Nach oben |
|
 |
OneCypher
Anmeldungsdatum: 23.09.2007 Beiträge: 802
|
Verfasst am: 05.12.2007, 16:15 Titel: |
|
|
Code: |
Dim Shared threadsync As Any Ptr
dim shared threadhandles(1 to 64) as any ptr
Type rng
ystart As Integer
ymax As Integer
End Type
Screen 19, 8
Sub Main (ByRef yrng As rng)
Dim As Integer X, Y, Count
Dim As Single Size, R, I, RTmp, Rs, Iss
Dim As Byte Ptr img = ImageCreate(800,1) ' eine Zeile
For Y = yrng.ystart To yrng.ymax
For X = 32 To 832-1'Trick statt img[X+32]
Count = 600
Size = 0
R = 0
I = 0
While Size < 4 And Count > 0
RTmp = R
Rs = R * R
Iss = I * I
R = Rs - Iss + ((X - 650) / 320)
I = (2 * RTmp * I) + ((Y - 300) / 320)
Size = Rs + Iss
Count -= 1
Wend
img[X]= (count Mod 256)
Next
MutexLock threadsync
Put (0,Y), img, pset
MutexUnlock threadsync
'sleep 1
Next
ImageDestroy img
End Sub
Dim As Double t1, t2, its(1 to 64)
dim ti as integer
dim tis as integer
Dim ranges(1 to 64) as rng
threadsync = MutexCreate
for ti = 1 to 16
t1 = Timer
for tis = 1 to ti
ranges(tis).ystart = (tis -1) * (600 / ti)
ranges(tis).ymax = (tis) * (600 / ti) -1
threadhandles(tis) = ThreadCreate(Cast(Any Ptr,@Main), @ranges(tis))
next
for tis = 1 to ti
ThreadWait(threadhandles(tis))
next
t2 = Timer
its(ti) = (800* 600) / (t2 - t1)
Cls
next
screen 0
cls
MutexDestroy(threadsync)
for ti = 1 to 16
print right(str(100+ti),2) & " Threads :" &its(ti) & " = " & (Int((its(ti)/its(1))*100) /100) & "fach"
next
Sleep
|
Was kommt bei euch bei rum? Bei mir erscheint:
Code: |
01 Threads :148592.5825305341 = 1fach
02 Threads :289835.1100156142 = 1.95fach
03 Threads :238899.2177942616 = 1.6fach
04 Threads :288182.8697226888 = 1.93fach
05 Threads :275320.4639361539 = 1.85fach
06 Threads :285752.7546248809 = 1.92fach
07 Threads :279970.9981150043 = 1.88fach
08 Threads :285944.5412854582 = 1.92fach
09 Threads :284902.0068636625 = 1.91fach
10 Threads :286739.2488146803 = 1.92fach
11 Threads :284812.9752651238 = 1.91fach
12 Threads :283677.6407688764 = 1.9fach
13 Threads :285582.0629210738 = 1.92fach
14 Threads :286108.0969108646 = 1.92fach
15 Threads :286539.3882051962 = 1.92fach
16 Threads :286605.7291136642 = 1.92fach
|
Es kann allerdings sein das es nicht unbedingt genau die selben ergebnisse ausgibt als würde man die threads ausserhalb der schleife in fester anzahl starten.. es werden ja bei jedem neuen Thread-test die bereiche neu berechnet. Dies Fließt noch in die Zeitberechnung mit ein. Weiss aber nicht so genau wie ich die ausserhalb der schleife berechnen soll... |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|