Also beim Lesen kommen ganz viele Punkte zum tragen:
a) Caching. Du willst nur eine Zeile lesen und das sind von mir aus 70 Bytes. Die heutigen Medien können das aber so nicht lesen. Dort wird Blockweise gelesen, d.h. es wird immer ein ganzer Datenblock gelesen z.B. 4 oder 8 KB. Aus dem Grund gibt es meist ein Caching, damit der Block einmal gelesen wird und so das Medium nicht erneut beansprucht werden muss wenn dann die nächste Zeile gelesen wird.
b) Diverse Speichermedien: Neben den herkömmlichen Festplatten gibt es auch SSDs oder gar Ramdisks (mit gepuffertem Speicher, so dass diese Speicherbereiche sogar einen Reboot überleben können und so!)
Hier hast Du dann einen ganz anderen Zugriff und es spielt keine Rolle mehr, wo Daten gelesen werden müssen. Dieses Versetzen eines Schreib-/Lesekopfes gibt es nicht mehr.
Dann muss man auch noch sehen:
c) Es wird ja nicht nur gelesen, sondern es wird etwas mit den Daten gemacht. Dadurch gibt es dann Verzögerungen. Solche Verzögerungen können also durchaus für andere IO Operationen genutzt werden.
IO Operationen sind übrigens nicht nur Zugriffe auf Festplatten und so. Sondern hier wird generell die Datenübertragung zwischen zwei Komponenten betrachtet. Und hier ist dann immer der Übertragungsweg und die Auslastung der Komponenten zu betrachten. Daher wurden Technologien eingeführt, dass hier auch eine Entlastung stattfinden kann (z.B. Direct Memory Access DMA, womit gewisse Zugriffe auf den Speicher nicht mehr über die CPU laufen müssen.)
Wenn wir dies auf Deinen Fall anwenden, dann ist es so, dass jeder Thread Daten liest (in gewissen Blöcken). Teilweise, nicht immer, wird dadurch ein Zugriff auf die Festplatte notwendig und es wird ein Block an Daten gelesen.) Wenn der Block gelesen wurde kann der Thread die Daten verarbeiten, d.h. es kommt zu mehreren Zugriffen auf den gelesenen Block ohne dass die Festplatte angesprochen werden muss.
Dies bedeutet, dass es eine Reihe Threads geben kann, die parallel arbeiten können. Die Frage ist, wie lange das Lesen des Blocks gedauert hat und wie lange die Abarbeitung des Blocks dauert.
Angenommen das Lesen kostet 1 Zeiteinheit und die Verarbeitung 4 Zeiteinheiten:
Dann können 5 Threads die Platte ausnutzen:
1. Thread liest Block von Platte
2. - 5. Thread wartet auf Zugriff auf Platte
---
1. Thread verarbeitet (1/4)
2. Thread liest Block von Platte
3.-5. Thread wartet auf Zugriff auf Platte
---
1. Thread verarbeitet (2/4)
2. Thread verarbeitet (1/4)
3. Thread liest Block von Platte
4. / 5. Thread wartet
---
1. Thread verarbeitet (3/4)
2. Thread verarbeitet (2/4)
3. Thread verarbeitet (1/4)
4. Thread liest Block von Platte
5. Thread wartet
---
1. Thread verarbeitet (4/4)
2. Thread verarbeitet (3/4)
3. Thread verarbeitet (2/4)
4. Thread verarbeitet (1/4)
5. Thread liest Block von Platte
---
Jetzt startet es wieder von oben, nur eben haben wir jetzt gerade ein perfektes Szenario: Alles kann lesen oder ist am verarbeiten ... Es wartet niemand mehr....
Hier hat man also durch die 5 Threads ein Optimum heraus geholt. Statt 1 Bearbeitung in 5 Zeiteinheit haben wir 5 Bearbeitungen in den 5 Zeiteinheiten (So es lange genug so laufen kann.)
Diese anschauliche, vereinfachte Darstellung: Ist das dadurch verständlicher geworden?
Wichtig ist noch ein weiterer Punkt:
Teilweise muss zwischen Threads umgeschaltet werden. Du hast eine CPU mit x Threads, also können bis zu x Threads mehr oder weniger parallel ablaufen. Wenn Du aber nun mehr als x Threads hast (Was der default ist. Schau Dir nur einmal den Prozessmanager an, wie viele Prozesse aktuell auf Deinem Rechner laufen!), dann müssen die Arbeiten aufgeteilt werden.
Bildlicher Vergleich:
Du hast einen Stift und kannst mit dem schreiben. Nun bekommst Du aber mehrere Zettel und mehrere Anrufer: Du sollst für Anrufer etwas aufschreiben. Da aber niemand warten soll, schaltest Du zwischen den Anrufern ständig hin und her und die Anrufer sagen dann schnell, was Du weiter auf deren Zettel schreiben sollst. So kannst Du natürlich mit einem Stift auf 10 Zetteln mehr oder weniger gleichzeitig schreiben. Aber dieses Umschalten kostet Zeit: Du musst das Telefon auf den Anrufer umschalten und den Zettel des Anrufers zur Hand nehmen ==>
Da das Umschalten Zeit kostet, wird auch deutlich: Angenommen du sollst 100 Anrufer so parallel verarbeiten: Das dauert dann viel viel länger, als wenn Du die Anrufer einer nach dem anderen abarbeitest.
Parallelisierung bringt also nur dann etwas, wenn Du so Pausen ausgleichen kannst. (Ein Anrufer muss erst einmal nachdenken, was er noch aufgeschrieben haben will oder der Anrufer wartet noch auf eine Antwort seiner Frau bezüglich Einkaufszettel ... da wird die parallele Abarbeitung sehr stark.