![]() |
Generelle Fragen zu TParallel.For
Wie sicher mitbekommen bin ich vor Kurzem auf den TParallel-Zug mit aufgestiegen.
Bisher verläuft alles super. In Verbindung mit einer Thread-sicheren TStringList funktioniert bei mir nun alles einwandfrei und dennoch habe ich ein paar Fragen. 1. bringt eine TParallels.For-Schleife irgendwelche Vorteile gegenüber der normalen For-Schleife auf einem 1-Kern-System? 2. ich lasse einiges an kleinen Log-Daten (unter 100 KB) in einem TThread kopieren. Das geschieht dann über TParallels.For IM TThread. - wenn ich die Daten mit einem TSHFileOpStruct-Konstrukt kopiere scheint es schneller zu sein als Windows.CopyFileEx (ohne CallBack-Funktion). - könnte das an TParallel.For liegen oder ist das "manuelle" kopieren mit TSHFileOpStruct einfach besser (weil weniger Overhead) als CopyFileEx in einem Thread? 3. Ich habe keinen Unterschied bemerkt. Aber gibt es einen Unterschied zwischen TParallels.For und TParallels.&For? 4. Ich denke eher nicht, dass man die Threadanzahl von TParallels.For selbst bestimmen kann. Wenn doch, wie? Ich habe etwas von einem Threadpool gelesen, es aber nicht ganz verstanden. |
AW: Generelle Fragen zu TParallel.For
Hallo
Zitat:
Zitat:
|
AW: Generelle Fragen zu TParallel.For
Zitat:
Zitat:
|
AW: Generelle Fragen zu TParallel.For
Zitat:
Beschleunigen kannst du so etwas am ehesten indem du selbst die Dateien in den Arbeitsspeicher einliest und in einem Rutsch schreibst. Groß wird der Vorteil dadurch aber nicht unbedingt sein bei der Dateigröße. |
AW: Generelle Fragen zu TParallel.For
Kopiert werden 5000 x 56,1 KB (FileFiller) von HDD auf einen etwas älteren USB-Stick. Das alles in 4 bis 5 Minuten.
Die Schreibgeschwindigkeit meiner Demo liegt laut Berechnung bei etwa 0,9 bis 1,1 MB pro Sekunde (4 erzeugte Threads, jeder Thread mit TParallel.For, laut TaskManager 40+ Threads). Die am Ende berechnete durchschnittliche Schreibgeschwindigkeit liegt bei etwa 850 KB pro Sekunde (15 Dateien pro Sekunde). Windows benötigt dieselbe Zeit (mehrfach getestet, mit mehreren USB-Sticks, zwischenzeitlich formatiert usw.) |
AW: Generelle Fragen zu TParallel.For
Klar, wenn du nur lesend auf die Festplatte zugreifst und einen langsameren Flashspeicher zum Schreiben nutzt, hast du das Problem nicht.
Die maximale Anzahl der Operationen des Flashspeichers pro Sekunde ist aber gleich, ob mit einem oder mit mehreren Threads. |
AW: Generelle Fragen zu TParallel.For
Ich habe das gerade mal mit Quelle Festplatte D und Ziel Festplatte D gemacht.
Der Festplatten-Cache war denke ich leer, da der PC gerade erst gestartet wurde. Zumindest waren nicht bereits die Daten im Cache die ich kopiert habe. Das hat 59 Sekunden gedauert. Gleicher Test wie oben: 5000 Dateien je 56,1 KB mit FileFiller erstellt. |
AW: Generelle Fragen zu TParallel.For
Eine Frage habe ich leider noch.
Ich versuche gerade möglichst viel auf TParallels.For umzustellen. Ich habe eine for-Schleife welche eine TObjectList füllt. Reicht es hier, wenn ich drumherum mit Queue(procedure begin end); arbeite? Der Rest mit den Variablen ist alles kein Problem dank TInterlocked. |
AW: Generelle Fragen zu TParallel.For
TParallel.For mag zwar verlockend sein, aber wenn du zu viel Synchronisation, Queue, ... benötigst, ist es nicht unbedingt die beste Lösung. Oft ist eine manuelle Lösung mit Threads schneller.
Das kommt vor allem darauf an wie lange ein einzelner Durchlauf dauert. Wenn du z.B. 10000 Schleifendurchläufe hast, die sequentiell 3 Sekunden dauern, macht es eher Sinn das ganze in z.B. 4-8 Threads mit je 1250-2500 Durchläufen aufzuteilen und die Ergebnisse nur noch am Ende zusammenzuführen. Denn dann sparst du dir viel Overhead, so dass das ganze am Ende oft schneller ist. Insbesondere weil die meisten Rechner auch nur 4-8 Kerne haben. Zur Frage: Ja, Queue reicht. Aber wenn du das zu oft benutzt, ist das wie gesagt ein ziemlicher Verwaltungsaufwand. |
AW: Generelle Fragen zu TParallel.For
Ich habe deinen Rat befolgt.
Ich verwende nun 2x TTask.Run(); In jedem dieser rufe ich eine einzige bestimmte Funktion auf, welche durch meine StringListe geht (einige Parameter, zudem Start und Ende der For-Schleife) Folgendermaßen berechne ich, welcher der beiden Runs was zu bearbeiten hat
Delphi-Quellcode:
Wenn der zweite Aufruf von dummyFunction fertig bevor der erste fertigist, wartet der zweite Aufruf (Boolean Variable), bis der erste komplett.. komplett.. fertig ist.
run1 := 0;
run2 := 0; // Beispiel: sl.Count = 5001 for i := 0 to (sl.Count div 2) - 1 do // 0 bis 2500 Inc(run1); for i := run1 to sl.Count - 1 do // 2501 bis 5000 Inc(run2); TTask.Run( procedure begin TThread.Queue(nil, procedure begin dummyFunction(param1, param2, ..., 0, run1); end); end); TTask.Run( procedure begin TThread.Queue(nil, procedure begin dummyFunction(param1, param2, ..., run2, sl.Count - 1); end); end); Am ende des zweiten Aufrufs wird in dummyFunction() alles zusammengeführt (nur ein paar Zählervariablen). Vorher brauchte das mit meinen Testdaten 2,1 bis 2,2 Sekunden im Schnitt. Nun bin ich bei 1,4 bis 1,5 im Schnitt. Ich denke ich werde noch etwas einbauen, dass das TTask.Run nur bei Mehrkernsystemen verwendet wird. Schöner wär's natürlich, wenn das alles super dynamisch wäre, ohne feste Variablen wie meine booleschen aktuell. Aber das kommt später wenn ich den Durchblick habe. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz