Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

"Kleiner" Thread-Benchmark?
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
OneCypher



Anmeldungsdatum: 23.09.2007
Beiträge: 802

BeitragVerfasst am: 28.11.2007, 15:16    Titel: "Kleiner" Thread-Benchmark? Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
OneCypher



Anmeldungsdatum: 23.09.2007
Beiträge: 802

BeitragVerfasst am: 28.11.2007, 16:49    Titel: Auch ganz witzig... Antworten mit Zitat

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 grinsen

->Bin der Erfinder des "Threadrauschends" grinsen

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
Benutzer-Profile anzeigen Private Nachricht senden
Mao



Anmeldungsdatum: 25.09.2005
Beiträge: 4409
Wohnort: /dev/hda1

BeitragVerfasst am: 28.11.2007, 18:17    Titel: Antworten mit Zitat

Mit Sleep 1 -> 65.
Ansonsten zwischen 17000 und 25000.
_________________
Eine handvoll Glück reicht nie für zwei.
--
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 28.11.2007, 19:46    Titel: Antworten mit Zitat

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 verlegen (dafür mag ich es bunter grinsen )
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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 29.11.2007, 00:11    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
ThePuppetMaster



Anmeldungsdatum: 18.02.2007
Beiträge: 1839
Wohnort: [JN58JR]

BeitragVerfasst am: 29.11.2007, 06:58    Titel: Antworten mit Zitat

ö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
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 29.11.2007, 12:50    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
atari
gesperrt


Anmeldungsdatum: 26.08.2007
Beiträge: 144

BeitragVerfasst am: 29.11.2007, 20:02    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Mao



Anmeldungsdatum: 25.09.2005
Beiträge: 4409
Wohnort: /dev/hda1

BeitragVerfasst am: 29.11.2007, 20:07    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Stormy



Anmeldungsdatum: 10.09.2004
Beiträge: 567
Wohnort: Sachsen - wo die schönen Frauen wachsen ;)

BeitragVerfasst am: 29.11.2007, 23:43    Titel: Antworten mit Zitat

@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. happy 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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 30.11.2007, 00:41    Titel: Antworten mit Zitat

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 zwinkern
_________________
"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
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 30.11.2007, 15:38    Titel: Antworten mit Zitat

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 verwundert
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. verwundert
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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Mao



Anmeldungsdatum: 25.09.2005
Beiträge: 4409
Wohnort: /dev/hda1

BeitragVerfasst am: 30.11.2007, 15:54    Titel: Antworten mit Zitat

@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. neutral
Wundert mich trotzdem. neutral
_________________
Eine handvoll Glück reicht nie für zwei.
--
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
MisterD



Anmeldungsdatum: 10.09.2004
Beiträge: 3071
Wohnort: bei Darmstadt

BeitragVerfasst am: 30.11.2007, 17:03    Titel: Antworten mit Zitat

könnte auch am pipelining liegen volta zwinkern 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
Benutzer-Profile anzeigen Private Nachricht senden
Bimi



Anmeldungsdatum: 03.12.2007
Beiträge: 66

BeitragVerfasst am: 03.12.2007, 20:14    Titel: Re: "Kleiner" Thread-Benchmark? Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
OneCypher



Anmeldungsdatum: 23.09.2007
Beiträge: 802

BeitragVerfasst am: 05.12.2007, 12:21    Titel: Antworten mit Zitat

Tatsache ist, das ich mit dem proggi von Volta eine beschleunigung von 1,9fach hinbekomme lächeln .. das ist doch schon mal ne adresse grinsen

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 lächeln danke an alle!! Dieser thread macht echt spaß mit euch!!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
OneCypher



Anmeldungsdatum: 23.09.2007
Beiträge: 802

BeitragVerfasst am: 05.12.2007, 12:30    Titel: Antworten mit Zitat

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 grinsen
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 05.12.2007, 13:47    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
OneCypher



Anmeldungsdatum: 23.09.2007
Beiträge: 802

BeitragVerfasst am: 05.12.2007, 15:26    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
OneCypher



Anmeldungsdatum: 23.09.2007
Beiträge: 802

BeitragVerfasst am: 05.12.2007, 16:15    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
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.

 Impressum :: Datenschutz