multicore programmierung



  • bedenke schrieb:

    Jester schrieb:

    prozess-wechsel sind teuer, thread-wechsel dagegen nicht sooo sehr.

    Da sparen alle immer beim ++iter statt iter++, aber dann 100 unnötige Taskwechsel machen.

    ++iter kommt meistens in Schleifen vor. Hier wird das ganze also nicht nur einmal, sondern meistens verdammt oft hintereinader gemacht, weshalb kleine Unterschiede schnell große auswirkungen haben können.

    Meiner Erfahrung nach führen ein paar Threads zu viel zu kaum schlechterer Leistung, wohingegen zu wenig Threads schnell zu heftigem Performance-Verlust führen.

    Dennoch sollte man natürlich nicht grundlos einfach mehr Threads starten, als man braucht, es sei denn es macht die Arbeit einfacher, weil das Problem tatsächlich aus mehreren unabhängigen parallel ablaufenden Dingen besteht.
    Am besten verwendet man eine Abstraktionsschicht, die automatisch sinnvoll parallelisier, wenn es nur zu Performance-Zwecken dient.



  • bedenke schrieb:

    Jester schrieb:

    prozess-wechsel sind teuer, thread-wechsel dagegen nicht sooo sehr.

    Da sparen alle immer beim ++iter statt iter++, aber dann 100 unnötige Taskwechsel machen.

    hehe, da ist natürlich was dran. allerdings ist es an der stelle wo man das macht vom ergebnis her wirklich egal welche variante man verwendet. sobald man sich also mal an das präfix-teil gewöhnt hat passt alles und man verliert nie was und manchmal (vermutlich ziemlich selten) gewinnt man auch mal was.

    ich wollte auch nicht sagen, dass es eine großartige idee ist unheimlich viele threads zu erzeugen, es ist sicher besser eine auf das system zugeschnittene Anzahl zu erzeugen. Trotzdem sollte man den Aufwand für einen Threadwechsel nicht überschätzen, der besteht nämlich im Wesentlichen aus dem Umhängen des Stackpointers, also einer wirklich schnellen Operation.



  • Jester schrieb:

    Trotzdem sollte man den Aufwand für einen Threadwechsel nicht überschätzen, der besteht nämlich im Wesentlichen aus dem Umhängen des Stackpointers, also einer wirklich schnellen Operation.

    Also soweit ich mich erinnere muss man die Register auch noch sichern bzw. wiederherstellen.

    Aber stimmt, ist eigentlich egal ob 10 oder 100 Threads, wenn du vernünftige Datenmengen hast, ist das sowieso nur Mikro-Optimierung. Richtig optimiert wird (meistens) anders.



  • ich möchte an dieser stelle noch einmal meine meinung kundtun:

    "...wurde auf 4 cores optimiert" ist marketing shit 🙂



  • sothis_ schrieb:

    ich möchte an dieser stelle noch einmal meine meinung kundtun:

    "...wurde auf 4 cores optimiert" ist marketing shit 🙂

    marketing ja, shit nicht zwingend. denn bei mehreren prozessoren ist es durchaus von vorteil es auch darauf auszulegen. Wenn das programm allerdings eh nur geringste anforderungen an die cpu stellt, ist es egal^



  • Hmm was macht man eigentlich, wenn man jetzt z.B. 2 Threads hat, die sehr rechenintensive Aufgaben bewältigen - kann man da irgendwie dafür sorgen, daß beide möglichst auf unterschiedlichen Kernen laufen? Also quasi daß man diesen Wunsch dem Betriebssystem gegenüber äußert, und dieses dann sagt "ja, okay, ich werd mal sehen was sich machen läßt" 😉

    Braucht man dazu sowas wie OpenMP, oder geht sowas auch mit einfacheren Mitteln?



  • bedenke schrieb:

    Jester schrieb:

    Trotzdem sollte man den Aufwand für einen Threadwechsel nicht überschätzen, der besteht nämlich im Wesentlichen aus dem Umhängen des Stackpointers, also einer wirklich schnellen Operation.

    Also soweit ich mich erinnere muss man die Register auch noch sichern bzw. wiederherstellen.

    kommt drauf an, in wie weit die hardware dafür unterstützung bietet. aber in einigen fällen sollte man die 'context switch latency' schon beachten. einige microsekündchen gehen dabei schon verloren.
    🙂



  • Rock Lobster schrieb:

    Hmm was macht man eigentlich, wenn man jetzt z.B. 2 Threads hat, die sehr rechenintensive Aufgaben bewältigen - kann man da irgendwie dafür sorgen, daß beide möglichst auf unterschiedlichen Kernen laufen?

    Das sollte eigentlich jedes halbwegs modernes BS automatisch machen 🙂



  • Auch wenn ich mich jetzt vielleicht etwas noobig anhöre, aber kann das OS denn tatsächlich "rausfinden", für welche Threads sich das Aufteilen auf mehrere Kerne lohnt? Eigentlich arbeitet doch eh jeder Thread ununterbrochen seinen Kram ab, und das OS dürfte eigentlich auch nicht wissen, welcher Thread wie lange noch laufen wird, daher hab ich grad echt keine Vorstellung davon, wie das OS nun wissen könnte, welche Threads es am besten auf getrennten Kernen laufen läßt.



  • Badestrand schrieb:

    Rock Lobster schrieb:

    Hmm was macht man eigentlich, wenn man jetzt z.B. 2 Threads hat, die sehr rechenintensive Aufgaben bewältigen - kann man da irgendwie dafür sorgen, daß beide möglichst auf unterschiedlichen Kernen laufen?

    Das sollte eigentlich jedes halbwegs modernes BS automatisch machen 🙂

    ein BS versucht normalerweise die threads auf alle kerne gleichmässig zu verteilen. wenn man pech hat, laufen beide threads auf dem gleichen kern.
    🙂



  • Rock Lobster schrieb:

    Auch wenn ich mich jetzt vielleicht etwas noobig anhöre, aber kann das OS denn tatsächlich "rausfinden", für welche Threads sich das Aufteilen auf mehrere Kerne lohnt? Eigentlich arbeitet doch eh jeder Thread ununterbrochen seinen Kram ab, und das OS dürfte eigentlich auch nicht wissen, welcher Thread wie lange noch laufen wird, daher hab ich grad echt keine Vorstellung davon, wie das OS nun wissen könnte, welche Threads es am besten auf getrennten Kernen laufen läßt.

    Naja, das BS übernimmt ja auch das Scheduling, teilt also den Threads den Prozessor zu und zieht sie wieder von ihm ab. Viele Threads im System warten immer nur auf ein Ereignis, bei denen wird nur kurz eine Bedingung überprüft und der nächste Thread kommt an die Reihe. Wenn ein Thread seine volle Zeitscheibe verbraucht, weiß das BS damit, dass er viel zu arbeiten hat; so kann das BS die voll arbeitenden Threads leicht auf die Prozessoren verteilen.



  • fricky schrieb:

    ein BS versucht normalerweise die threads auf alle kerne gleichmässig zu verteilen. wenn man pech hat, laufen beide threads auf dem gleichen kern.
    🙂

    Wenn alle anderen Kerne ausgelastet sind, dann ist das natürlich gut möglich. Dann spielt's aber auch keine Rolle, auf welchen Kernen die Threads laufen.



  • Jester schrieb:

    Trotzdem sollte man den Aufwand für einen Threadwechsel nicht überschätzen, der besteht nämlich im Wesentlichen aus dem Umhängen des Stackpointers, also einer wirklich schnellen Operation.

    Werden bei den meisten Betriebssystemen die Prozesse nicht ohnehin alle n Sekunden (n << 1) unterbrochen und das Scheduling erneut durchgeführt, egal wieviele Threads man hat?

    Moderne Betriebssysteme haben doch ohnehin O(1) Scheduler.



  • @Rock Lobster: Ich habe schon damit rumexperimentiert einzelne Threads an bestimmte Kerne zu binden und ich war nie erfolgreich. Das automatische Scheduling des OS war immer besser, als ich.



  • Ok, wie finde ich in C++ die Anzahl der Cores heraus?

    Baue gerade einen Raytracer, da dürfte es ja dann sinvoll sein genau so viele threads wie cores zu haben. Macht jeder core einen bildabschnitt... Oder is das zu vereinfacht gedacht?



  • Helium schrieb:

    @Rock Lobster: Ich habe schon damit rumexperimentiert einzelne Threads an bestimmte Kerne zu binden und ich war nie erfolgreich. Das automatische Scheduling des OS war immer besser, als ich.

    --> http://en.wikipedia.org/wiki/Processor_affinity
    (unten die links zu MSDN, falls du das für windows brauchst)



  • Georg1983 schrieb:

    Ok, wie finde ich in C++ die Anzahl der Cores heraus?

    Baue gerade einen Raytracer, da dürfte es ja dann sinvoll sein genau so viele threads wie cores zu haben. Macht jeder core einen bildabschnitt... Oder is das zu vereinfacht gedacht?

    OpenMP ist ein Stickwort.



  • ich wuerde auch openMP empfehlen. simple und dafuer recht gute art multicore auszunutzen. man muss keine threadpools usw selber verwalten, es ist sehr stabil und hat recht komplexe program-flows (z.b. threads die wieder jobs in subthreads aufteilen).
    und die integration mit ein paar pragmas ist echt simpel.



  • fricky schrieb:

    Helium schrieb:

    @Rock Lobster: Ich habe schon damit rumexperimentiert einzelne Threads an bestimmte Kerne zu binden und ich war nie erfolgreich. Das automatische Scheduling des OS war immer besser, als ich.

    --> http://en.wikipedia.org/wiki/Processor_affinity
    (unten die links zu MSDN, falls du das für windows brauchst)

    Ich verstehe deine Antwort nicht. Ich habe Threads an bestimmte Kerne gebunden. Allerdings waren die Ergebnisse immer schlechter, als wenn ich das dem Betriebssystem überlassen habe.



  • Helium schrieb:

    Allerdings waren die Ergebnisse immer schlechter, als wenn ich das dem Betriebssystem überlassen habe.

    ^^ so hättest du es vielleicht schreiben sollen.
    🙂


Anmelden zum Antworten