Wydajność aplikacji wielowątkowej

Odpowiedz Nowy wątek
2019-08-17 17:44
0

Ostatnio próbuję ogarnąć wielowątkowość i wykorzystać ją do zwiększenia wydajności mojego silnika (głównie w zakresie renderowania). Napisałem sobie proste demko:

type
  TTest = class(TThread)
    procedure Execute; override;
  end;

var
  Test: array[0..4] of TTest;
  C: Integer = 0;
  F: Integer = 0;
  Before, After: Int64;

procedure Loop;
var
  I: Integer;
begin
  for I := 0 to 1000 do Inc(F, 1);
  Inc(C, 1);
  if C = 5 then
    begin
      QueryPerformanceCounter(After);
      ShowMessage(IntToStr(After - Before));
    end;
end;

procedure TTest.Execute;
begin
  Loop;
end;

procedure Start;
var
  I: Integer;
begin
  QueryPerformanceCounter(Before);
  for I := 0 to 4 do Test[I].Resume;
end;

initialization
  Test[0] := TTest.Create(True);
  Test[1] := TTest.Create(True);
  Test[2] := TTest.Create(True);
  Test[3] := TTest.Create(True);
  Test[4] := TTest.Create(True);

Kod jest oczywiście prymitywny i robi wiele rzeczy, których się robić nie powinno (np. użycie w taki sposób zmiennych globalnych), ale to tylko dla testu. Problem mam taki, że całość działa strasznie wolno i nie rozumiem dlaczego.

Przy wywołaniu tego samego kodu w pętli (a więc bez dodatkowych wątków)

  for I := 0 to 4 do Loop;

jego wykonanie zajmuje jakieś 80-90 ticków procesora. Z wieloma wątkami... to zależy. Gdy odpalam apkę z debugowaniem, zajmuje to od 60000 do 90000 ticków. Bez debugowania od 1000 do 3000.

Moje pytania:

  1. Robię coś źle? Jeżeli tak, to gdzie popełniam błąd?
  2. Czemu występuje taka różnica w szybkości wykonywania kodu i to na niekorzyść wielowątkowości?
  3. Czemu debugowanie lub jego brak, aż tak drastycznie wpływa na wydajność? W przypadku wywołania kodu w zwykłej pętli, taki problem wydaje się nie występować.
edytowany 1x, ostatnio: furious programming, 2019-08-18 01:17

Pozostało 580 znaków

2019-09-07 12:49
0

Prawdopodobnie Random() nie jest thread-safe, przez co padasz ofiarą false sharing oraz niesynchronizowanego dostępu do pamięci.


Pozostało 580 znaków

2019-09-07 13:59
0

Zmieniłem Random na 1234 * 4567, ale nie spowodowało to zmiany w szybkości. To znaczy zmieniła się ilość ticków potrzebna do wykonania zadania, ale nadal jest ona o wiele większa przy użyciu tasków, niż przy wywołaniu sekwencyjnym.

edytowany 1x, ostatnio: Crow, 2019-09-07 14:00

Pozostało 580 znaków

2019-09-07 14:10
0

A weź tam wstaw coś konkretnego, np kompresję 4 plików do ZIPów.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

2019-09-07 14:11
0

Tak jak już wspomniał @Wibowit:

Startowanie wątku zawsze trochę kosztuje,

Przerób swój kod tak, aby wykonywał obliczenia np. przez kilka milionów obrotów (albo robił coś sensownego, czego optymalizator od strzała nie wytnie w trakcie kompilacji), a powinieneś zauważyć różnicę.


edytowany 1x, ostatnio: Patryk27, 2019-09-07 14:11

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0