AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Generelle Fragen zu TParallel.For
Thema durchsuchen
Ansicht
Themen-Optionen

Generelle Fragen zu TParallel.For

Ein Thema von a.def · begonnen am 27. Dez 2016 · letzter Beitrag vom 1. Jan 2017
Antwort Antwort
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.367 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Generelle Fragen zu TParallel.For

  Alt 28. Dez 2016, 03:04
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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
a.def
(Gast)

n/a Beiträge
 
#2

AW: Generelle Fragen zu TParallel.For

  Alt 28. Dez 2016, 09:25
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.
  Mit Zitat antworten Zitat
a.def
(Gast)

n/a Beiträge
 
#3

AW: Generelle Fragen zu TParallel.For

  Alt 30. Dez 2016, 21:37
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.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.367 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Generelle Fragen zu TParallel.For

  Alt 31. Dez 2016, 12:57
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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
a.def
(Gast)

n/a Beiträge
 
#5

AW: Generelle Fragen zu TParallel.For

  Alt 31. Dez 2016, 17:46
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:
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);
Wenn der zweite Aufruf von dummyFunction fertig bevor der erste fertigist, wartet der zweite Aufruf (Boolean Variable), bis der erste komplett.. komplett.. fertig ist.
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.

Geändert von a.def (31. Dez 2016 um 20:43 Uhr)
  Mit Zitat antworten Zitat
a.def
(Gast)

n/a Beiträge
 
#6

AW: Generelle Fragen zu TParallel.For

  Alt 31. Dez 2016, 20:50
Irgendetwas stimmt da mit meiner Zahlenkunst aber noch nicht.
Wenn ich eine StringListe mit 10 Einträgen habe:

Delphi-Quellcode:
{*
=> sl.Count = 10 Einträge

1:
- 0  bis (sl.Count-1) div 2 == 0 bis 4 (5 Strings)

2:
- 4+1 bis (sl.Count-1)      == 5 bis 9 (5 Strings)

*}
Nur wie müssen dann die Schleifen aussehen, die die Variablen hochzählen?
Delphi-Quellcode:
for i := 0 to ((sl.Count) div 2) - 1 do
 Inc(run1);

for i := run1 to sl.Count - 1 do
 Inc(run2);

ShowMessage('Von ' + IntToStr(0) + ' bis ' + IntToStr(run1) + sLineBreak + 'Von ' + IntToStr(run2) + ' bis ' + IntToStr(sl.Count - 1));
Das hier ergibt "0 bis 5" und "5 bis 9".
Bei ungeraden Zahlen (11 Einträge) ist es korrekt.

Geändert von a.def (31. Dez 2016 um 20:54 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#7

AW: Generelle Fragen zu TParallel.For

  Alt 31. Dez 2016, 21:15
In der ersten Schleife zählst Du von 0 bis zum berechneten Wert.

Mit diesem Wert beginnst Du die zweite Schleife. Die müsste aber beim ersten Wert hinter dem Ende der ersten Schleife beginnen.

Müsste es nicht eher so aussehen?
Delphi-Quellcode:
program Test;
var
        i : Integer;
        run1 : Integer;
        run2 : Integer;
        sl : TStringList;
begin
  sl := TStringList.Create;
  for i := 0 to 100 do sl.Add('');
  run1 := 0;
  run2 := 0;

  for i := 0 to (sl.Count div 2) do Inc(run1);

  for i := (run1 + 1) to sl.Count - 1 do Inc(run2);

  ShowMessage('Von ' + IntToStr(0) + ' bis ' + IntToStr(run1) + #13#10 + 'Von ' + IntToStr(run1 + 1) + ' bis ' + IntToStr(sl.Count - 1));
  sl.Free;
end.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:01 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz