Wie kann ich feststellen, ob ich Multithreading überbeanspruche?

15

Momentan habe ich das Gefühl, dass ich Multithreading überbeanspruche.

Ich habe 3 Arten von Daten, A, B und C.

Jedes Akann in mehrere Bs konvertiert werden und jedes Bkann in mehrere Cs konvertiert werden .

Ich interessiere mich nur für die Behandlung von Cs.

Ich könnte dies ziemlich leicht mit ein paar Konvertierungsfunktionen schreiben. Aber ich ertappte mich mit Themen der Umsetzung drei Warteschlangen ( queue_a, queue_bund queue_c). Es gibt zwei Threads, die die verschiedenen Konvertierungen durchführen, und einen Worker:

  • ConverterAliest aus queue_aund schreibt anqueue_b
  • ConverterBliest aus queue_bund schreibt anqueue_c
  • Worker behandelt jedes Element von queue_c

Die Konvertierungen sind ziemlich banal, und ich weiß nicht, ob dieses Modell zu verworren ist. Aber es scheint mir extrem robust zu sein. Jeder "Konverter" kann mit der Arbeit beginnen, noch bevor Daten in den Warteschlangen eingegangen sind, und zu jeder Zeit im Code kann ich einfach neue As oder Bs "einreichen" und es wird die Konvertierungs-Pipeline ausgelöst, die wiederum einen Job durch den Arbeiter auslöst Faden.

Sogar der resultierende Code sieht einfacher aus. Ich bin mir aber immer noch nicht sicher, ob ich Threads für etwas Einfaches missbrauche.

Exhuma
quelle
5
Ich denke, diese Frage muss etwas gekürzt werden, um sie zu beantworten. Der Titel ist auch irreführend - es hört sich so an, als würden Sie gleich einen Schimpanse veranstalten (obwohl Sie das nicht sind). Vielleicht sollten Sie etwas näher fragen: "Wie kann ich feststellen, ob ich Multithreading überbeanspruche?"
KChaloux
@KChaloux Ich stimme zu. Ich habe es bearbeitet und hoffe, dass es meine Gedanken ein bisschen besser einfängt.
Exhuma
4
@exhuma Super. Ihr -1 wird ein +1
KChaloux
3
@KChaloux ... der Unterschied, den ein Besuch auf dem Klo für Ihren Denkprozess
bedeuten
Dieses Online-PDF-Buch, Mature Optimization Handbook (vor wenigen Tagen veröffentlicht), befasst sich mit systematischen Effekten, bei denen der Einfluss eines Moduls auf die Gesamtsystemleistung manchmal den Bruchteil der Ausführungszeit des Moduls überschreitet .
rwong

Antworten:

16

Es ist fast immer einfacher, nacheinander zu denken und diese Logik später zu ändern, um die Verwendung von Threads zu verbessern. Und, wie der Ausdruck sagt: "Wenn es nicht kaputt ist, repariere es nicht." Die meisten Programmierer verwenden keine Threads, nur weil sie nicht benötigt werden.

Wenn Sie sich mit ihnen wohler fühlen, haben Sie mehr Kraft. Beachten Sie jedoch, dass Threads Ihr Programm mit ziemlicher Sicherheit verlangsamen, wenn sie keinen Geschwindigkeitsschub durch Beseitigung von Engpässen bieten.

Bedenken Sie auch, dass Systeme, die nur eine CPU für einen Prozess verwenden, mehrere Threads durch einen einzigen Thread simulieren, um Ressourcen zu sparen (dies ist bei modernen Computern nicht häufig der Fall, obwohl Smartphone-Anwendungen immer noch stark von diesem Missbrauch betroffen sind). In diesem Fall ist es sogar langsamer , wenn Sie Engpässe durch die Verwendung von Threads beseitigen, als wenn Sie überhaupt keine Threads verwendet haben.

Und, vielleicht der subtilste Grund, vorsichtig mit Threads umzugehen, aber sicherlich nicht der unwichtigste, Threads neigen dazu, das zu tun, was Sie nicht erwarten. Ja, wenn Sie Vorsichtsmaßnahmen treffen, sollten Sie in Ordnung sein. Ja, wenn Ihre Threads nicht in Variablen schreiben, die von Threads gemeinsam genutzt werden, sollten Sie in Ordnung sein. Allerdings sind Thread-bezogene Bugs sehr schwer zu finden. Da ich der Meinung bin, dass ein Programmierer die Möglichkeit, Fehler im Code zu erstellen, niemals vollständig ausschließen kann und daher ein Programmierer Maßnahmen zum Schutz vor möglichen Fehlern ergreifen sollte, anstatt sich darauf zu konzentrieren, diese Fehler vollständig zu beseitigen, sollten Sie diese Idee auf jeden Fall auf Hard- um auch Thread-Bugs zu finden. Mit anderen Worten, wissen Sie, dass trotz Ihrer allerbesten Bemühungen,

Solltest du trotzdem Threads verwenden? Nun, ein gesundes Wissen über Threads ist sicherlich keine schlechte Sache, besonders wenn Sie gut darin werden. Die Bewegung in letzter Zeit war jedoch in Richtung Singlethread-Sprachen wie node.js. Einer der Hauptvorteile eines einzelnen Threads besteht darin, dass er einfach zu skalieren ist und bestimmte Optimierungen vorgenommen werden können, wenn Sie wissen, dass die Anweisungen sequentiell ausgeführt werden sollen (auch wenn Optimierungen bedeuten können, dass Anweisungen parallel ausgeführt werden können asynchron ausgeführt werden).

Das heißt, ich sage tun, was für Sie am bequemsten ist. Nach meiner Erfahrung hat das Schreiben eines Programms, das Sie verstehen, eine höhere Priorität, als es schneller arbeiten zu lassen. Verwenden Sie Threads nur, wenn Sie der Meinung sind, dass sie Ihnen beim Schreiben des Programms helfen, und nicht, weil Sie möchten, dass es schneller funktioniert, da Sie sich nicht so sehr um die Leistung sorgen sollten, wie Sie das Programm schreiben (Optimierung ist wichtig, aber es ist wichtig) kann auch warten).

Neil
quelle
Sie machen interessante Punkte. In meinem Fall geht es bei der Konvertierungspipeline nicht um Leistung. Es geht um Code-Einfachheit / Lesbarkeit. Im Worker-Thread geht es um Leistung. Jede letzte Aufgabe wird auf einem Remotecomputer ausgeführt und durch das Übermitteln mehrerer Jobs wird die Ausführung erheblich beschleunigt.
Exhuma
2
@exhuma Neben der parallelen Ausführung über mehrere Threads können Sie auch asynchrone Techniken wie Futures / Promises oder einen Callback-orientierten Stil verwenden. Beachten Sie, dass Sie Pipelines modellieren können, indem Sie Iteratoren / Streams verketten. gibt es keine Notwendigkeit Threads tatsächlich verwenden - außer , wenn Sie mehrere CPUs nutzen wollen (im Code Vernetzung ist dies fast nie der Fall ist )
amon
@exhuma Ja, Threads helfen im Allgemeinen bei der Leistung. Mein Punkt war, dass, wenn Sie es nicht tun, weil es zu langsam ist, Sie es tun sollten, weil es Ihnen hilft, Ihr Programm zu schreiben. Die Optimierung sollte immer später erfolgen. Es kann sogar sein, dass das Entfernen von Threads aus Ihrem Programm es optimiert (obwohl dies für die meisten Programmierer nicht der Fall ist).
Neil
OT: Ich liebe deinen Avatar. Bringt mich zum Lächeln.
Marjan Venema
@exhuma, ich stimme dieser Antwort zu, möchte aber hinzufügen, dass, wenn Sie zur Vereinfachung des Codes Threads verwenden, dies in Ordnung ist. Seien Sie jedoch sehr vorsichtig, dass Sie die Threadsicherheit und mögliche Fallstricke mit mehreren Threads verstehen. Was wie ein einfaches Stück Multithread-Code erscheinen mag, könnte leicht versteckte Race-Bedingungen haben, die zu einer Reihe von sehr schwer auffindbaren Fehlern führen könnten.
Ben Lee