Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Delphi: jak określić maksymalną/optymalną ilość wątków?

leburaque 30 Sty 2012 15:57 6833 25
  • #1 30 Sty 2012 15:57
    leburaque
    Poziom 17  

    Witam.

    Mam nadzieję, że dobrze pojąłem temat wątków, więc zanim zapytam sprawdzę swą wiedzę.

    W moim programie pewna procedura wykonuje szereg obliczeń trwających godzinami. Mimo iż zużywa ona całość zasobów jej dostępnych, to jedynie 50% możliwości obliczeniowych dwurdzeniowego procesora. Jeśli dobrze rozumiem dołożenie drugiego wątku obciąży drugi rdzeń procesora, zatem obliczenia będzie można w efekcie wykonać szybciej (korzystając z pełnej mocy obliczeniowej procesora).

    I tu pojawia się pytanie: ponieważ docelowo chcę odpalać program na różnych komputerach, a jego obliczenia to skomplikowane operacje na tablicach 1000x1000 obiektów (akurat zoptymalizowałem co mogłem) chciałbym wiedzieć kilka rzeczy:

    1) Czy optymalna ilość wątków to ilość równa rdzeniom procesora? Ile maksymalnie można użyć wątków, żeby program wykonywał te działania możliwie najszybciej (zakładając, że nic innego komputer robić nie będzie musiał, a działanie tego programu jest docelowym jego zadaniem)? Czy da się to przewidzieć w prosty sposób, czy to bardziej skomplikowane?

    2) Czy istnieją w Delphi gotowe procedury odpowiedzialne za wykrycie i obliczenie optymalnej możliwej ilości wątków dla danego programu?

    Dziękuję za każdą informację.

    Pozdrawiam!

    0 25
  • #2 30 Sty 2012 17:36
    arnoldziq
    Moderator Programowanie

    1. Ilość dostępnych wątków, jest zależna przede wszystkim od ustawień systemu, którym dysonujesz. Inna będzie dla XP Home a inne dla XP Professional, Win7 Starter i Win7 Ultimate itd.
    2. Są. Poszukaj na forum. Nie dalej jak kilka tygodni temu, ten temat był poruszany.

    -1
  • #3 16 Lut 2012 14:36
    leburaque
    Poziom 17  

    Dobrze, poddaję się. Przepraszam, ale przejrzałem ostatnich parę miesięcy, używałem wyszukiwarki i google. Nie udało mi się zlokalizować tego tematu. W słowach kluczowych głównie różne kombinacje "delphi", "wątki", "wątek", "ilość". Poproszę w takim razie kogokolwiek o pomoc w znalezieniu postu:).

    Przy okazji chciałbym się o coś spytać. Każda procedura wywoływana przez utworzony przeze mnie wątek pracuje na zmiennych lokalnych, ale wyniki zapisuje w zmiennej globalnej. Czy to się będzie jakoś gryźć ze sobą?

    0
  • #4 16 Lut 2012 14:57
    arnoldziq
    Moderator Programowanie

    leburaque napisał:
    Dobrze, poddaję się. Przepraszam, ale przejrzałem ostatnich parę miesięcy, używałem wyszukiwarki i google. Nie udało mi się zlokalizować tego tematu. W słowach kluczowych głównie różne kombinacje "delphi", "wątki", "wątek", "ilość". Poproszę w takim razie kogokolwiek o pomoc w znalezieniu postu:).
    [Delphi] - Wątki, tabela watków problem z synchronizacją.
    Wątki

    leburaque napisał:
    Przy okazji chciałbym się o coś spytać. Każda procedura wywoływana przez utworzony przeze mnie wątek pracuje na zmiennych lokalnych, ale wyniki zapisuje w zmiennej globalnej. Czy to się będzie jakoś gryźć ze sobą?

    Będzie, ale można to obejść i zwracać wartość obliczeń wątku, do zablokowanej części oryginalnego wywołania.

    0
  • #5 16 Lut 2012 16:29
    leburaque
    Poziom 17  

    Nie wiem, czy jestem jakiś ślepy, czy coś... :)

    W podanym kodzie jedyne co ustalane jest to

    Kod: delphi
    Zaloguj się, aby zobaczyć kod


    czyli arbitralna stała. W rozdziale na 4programmers, a nawet kolejnych rozdziałach jedyne co jest napisane, to że "Nie zaleca się uruchamiania w tym samym czasie dużej ilości wątków w ramach tego samego procesu. Zalecana ilość to 16 wątków w ramach jednego procesu." I to wszystko niezależnie od architektury procesora, systemu i tak dalej? Pytałem o jakieś funkcje, albo biblioteki, które mogłyby wskazać mi ile wątków na danym sprzęcie max można odpalić.

    Jeśli chodzi o tablicę wątków, to zadeklarowałem ją tak:

    Kod: delphi
    Zaloguj się, aby zobaczyć kod


    I rozumiem, że tu nie będzie jakiegoś błędnego myślenia.

    Ale dalej zastanawia mnie co z tym "gryzieniem się" danych. Oto co robić ma każdy wątek:
    * z tablicy 1000x1000 elementów wybiera jeden;
    * sprawdza w globalnej zmiennej, czy inny wątek się tym elementem już nie zajmuje;
    * dokonuje obliczeń porównując dane z tablicy 1000x1000;
    * zmienia po otrzymaniu wyniku swój element w tablicy;

    Dlaczego to się będzie gryźć? Czy to znaczy, że kilka wątków nie może korzystać z jednej dużej tablicy?

    Dodano po 9 [minuty]:

    P.S. Czy jeśli wątek wywołuje globalną procedurę, która ma zadeklarowane lokalne zmienne, to czy kiedy trzy wątki wywołują tą samą procedurę, to zmienne przydzielane lokalnie się ze sobą "pogryzą"?

    0
  • #6 16 Lut 2012 16:42
    sedr
    Poziom 17  

    Ogólna zasada: ilość rdzeni + 1. Pisanie o 16 wątkach to bzdura.

    0
  • #7 16 Lut 2012 17:01
    leburaque
    Poziom 17  

    sedr napisał:
    Ogólna zasada: ilość rdzeni + 1. Pisanie o 16 wątkach to bzdura.


    plus czy minus? Tak dla bezpieczeństwa? (Oczywiście zakładamy, że jeśli wynik < 1 to wynik = 1:)

    0
  • #8 16 Lut 2012 18:16
    arnoldziq
    Moderator Programowanie

    sedr napisał:
    Ogólna zasada: ilość rdzeni + 1. Pisanie o 16 wątkach to bzdura.

    Drogi kolego.
    Bzdura, to dość mocne słowo. Załączam program, który udowodni, że kompletnie nie ma kolega racji.
    Mój program, zakłada kolejne wątki, których zadaniem jest tylko i wyłącznie mruganie światełkami na formie. Na dole pokazuje się ilość uruchomionych właśnie wątków. Światełka zmieniają się z czerwonych na zielone i odwrotnie.
    Każdy może się przekonać, ile jego system "zniesie" wątków.
    Ja, na swoim komputerze doszedłem do 51. Mam czterordzeniowy procesor Intel-a

    Delphi: jak określić maksymalną/optymalną ilość wątków?

    0
    Załączniki:
  • #9 17 Lut 2012 20:40
    leburaque
    Poziom 17  

    OK, rozumiem zatem, że to wymaga testów i arbitralnego ustalenia, tak? Nie ma jakiejś funkcji w samym Delphi albo czegoś co pozwoliłoby na ustalenie optimum? Chodzi mi o coś co pozwoli mi na przydzielenie innej ilości wątków w przypadku jednordzeniowych procesorów... Jak to sprawdzać w programie a nie w ustaleniach użytkownika?

    I teraz druga rzecz: o dziwo nic mi się nie gryzie w zmiennych, wątki śmigają piknie panocku, generują poprawne wyniki i aż serce rośnie. Mam jednak problem z rysowaniem podczas działania programu. Mogę się bez tego obyć, ale wygodniejsza jest wówczas obserwacja wyników. Jeśli cokolwiek próbuję wyświetlić w (tak mi się wydaje) losowych momentach kompilator trzaska błąd:

    "canvas does not allow drawing"

    Żeby zbadać co jest problemem usuwałem po kolei linijki na których wykrzaczał się program. W efekcie - jedynie cokolwiek co zawierało Canvas "zawieszało" wątki.

    https://www.elektroda.pl/rtvforum/topic1117086.html - tutaj znalazłem informację o synchronizacji. http://4programmers.net/Delphi/Kompendium/Rozdzia%C5%82_8#id-Synchronizacja - widzę to też tutaj i tutaj - http://forum.4programmers.net/Delphi_Pascal/120238-Zaawansowane_Czy_uzywac_Synchronize_watki

    Ale - za przeproszeniem - nie rozumiem metody. Czy ktoś mógłby mi nieco jaśniej określić co mam ładować do Synchronize()?

    Przepraszam, że nieco spłycam wątek takim pytaniem, ale właśnie o wątki rzecz idzie...

    Dodano po 2 [minuty]:

    P.S. Doszedłem do 16 wątków na swoim dwurdzeniowym AMD Thurionie 64 X2 TL-60.

    Słabo w porównaniu z Twoim:)

    0
  • #10 17 Lut 2012 22:34
    LED5W
    Poziom 32  

    arnoldziq napisał:
    Każdy może się przekonać, ile jego system "zniesie" wątków.
    Ja, na swoim komputerze doszedłem do 51. Mam czterordzeniowy procesor Intel-a
    Jak ten koniec wykryć? :D U siebie to uruchomiłem na czterordzeniowym i7 (8 procesorów logicznych) i do 7 wątków wszystko działa normalnie. Przy 8, wiadomo, widać spowolnienie i przycięcia. Jednak uruchomienie programu z najniższym priorytetem umożliwia normalną pracę (wymagającą mało mocy obliczeniowej ;)) nawet 519 wątków (więcej nie próbowałem, bo się kwadraciki nie mieszczą :P).
    Taki wzorek mi wyszedł:
    Delphi: jak określić maksymalną/optymalną ilość wątków?

    Po kliknięciu exit wyskoczyło mi:
    Delphi: jak określić maksymalną/optymalną ilość wątków?

    A co do tej ilości wątków to myślę, że najlepiej tworzyć ich tyle ile jest procesorów logicznych i uruchamiać z niższym priorytetem, żeby nie "mulić" interfejsu.

    0
  • #11 18 Lut 2012 00:33
    arnoldziq
    Moderator Programowanie

    Dokładnie.
    Jeżeli ustali się priorytet na niski, to można zaszaleć. :)
    Nie chodzi o ustalenie ilości, ale o udowodnienie, że (cytuję) "mówienie o 16 wątkach to bzdura" to jest właśnie ta bzdura.
    Błąd który się pokazał, to problem ze zwalnianiem pamięci po procesach.
    Przyznam się, że nie chciało mi się w to zagłębiać i poprawiać :)

    0
  • Pomocny post
    #12 18 Lut 2012 17:42
    LED5W
    Poziom 32  

    leburaque napisał:
    I teraz druga rzecz: o dziwo nic mi się nie gryzie w zmiennych, wątki śmigają piknie panocku, generują poprawne wyniki i aż serce rośnie. Mam jednak problem z rysowaniem podczas działania programu. [...] Jeśli cokolwiek próbuję wyświetlić w (tak mi się wydaje) losowych momentach kompilator trzaska błąd:

    "canvas does not allow drawing"

    Żeby zbadać co jest problemem usuwałem po kolei linijki na których wykrzaczał się program. W efekcie - jedynie cokolwiek co zawierało Canvas "zawieszało" wątki.
    A nie rysujesz przypadkiem w tym "roboczym" wątku?

    0
  • Pomocny post
    #13 18 Lut 2012 18:13
    Dżyszla
    Poziom 42  

    Generalnie to nie ma jakiejś konkretnie określonej liczby. Dobranie ilości wątków zależy od zadań, ich charakteru oraz sprzętu i systemu. Właściwy dobór wątków to kompromis pomiędzy ilością mocy obliczeniowej wykorzystywanej przez nie wszystkie a ilością mocy obliczeniowej potrzebnej na zarządzanie nimi. Więc w ekstremalnym przypadku procesor nie będzie robił nic, poza zarządzaniem wątkami. To po prostu wymaga testów wydajnościowych w każdym jednym środowisku.

    Na studiach bardzo podobne zagadnienie przerabiałem, a mianowicie wpływu buforowania danych na szybkość działania operacji (chodziło o przeprowadzanie zapisu na dysk w osobnym wątku). Poniżej zamieszczam część ze sprawozdania. Dotyczyło ono programu Top Secret Media.

    0
  • #14 19 Lut 2012 23:58
    leburaque
    Poziom 17  

    LED5W napisał:
    A nie rysujesz przypadkiem w tym "roboczym" wątku?


    Tak. Rysuję bezpośrednio na formie.

    Nauczyłem się w międzyczasie obsługiwać Synchronize, ale nawet jeśli wywołuję rysowanie poprzez Synchronize, to efekt jest ten sam.

    Dodano po 3 [minuty]:

    Dżyszla napisał:
    To po prostu wymaga testów wydajnościowych w każdym jednym środowisku.


    Rozumiem zatem, że powinienem napisać jakiś podprogram, który by testował po prostu wydajność działania, tak? To akurat da się zrobić.

    Pomysł mam taki: algorytm mierzy czas operacji dla wykonanych wszystkich wątków. Poczynając od 1 wątku co operację dodaje jeden wątek. Dopóki średni czas pracy wątku jest podobny do czasu pracy pojedynczego wątku - jest dobrze. Gdy drastycznie spada średnia prędkość - to oznacza granicę krytyczną.

    Może coś takiego?

    0
  • Pomocny post
    #15 20 Lut 2012 07:16
    Dżyszla
    Poziom 42  

    Moim zdaniem lepiej napisać procedurę testującą, która pozwoli automatycznie ustawić właściwą ilość. Robiłaby to samo, co zadanie, tyle że mierzyła czas (co jest dodatkowym obciążeniem!) i próbowała dla różnych opcji (najlepiej poszukiwanie metodą bisekcji).

    A to zadanie poważnie jest aż tak skalowalne i nieliniowe?

    0
  • #16 20 Lut 2012 13:56
    LED5W
    Poziom 32  

    Rysowanie powinno być raczej w jednym wątku.

    Proponuję jednak spróbować ustawić ilość wątków na ilość procesorów logicznych. Jeżeli jednak będziesz chciał napisać taką procedurę testującą pamiętaj o innych procesach, które mogą w znacznym stopniu zużywać czas procesora.

    0
  • #17 20 Lut 2012 19:53
    blue_17
    Poziom 32  

    Czy mógłbym prosić taki przykład z progres barami tylko dla lazarusa bo wiem że tam może się to nieco różnić

    Pozdrawiam

    0
  • #18 21 Lut 2012 17:36
    sedr
    Poziom 17  

    Moje stwierdzenie nie odnosiło się do tego, że nie można zrobić 16 wątków, tylko do tego, że nie ma to sensu w większości zagadnień. Programowanie współbieżne jest skomplikowanym zagadnieniem nawet dla doświadczonych koderów. Mamy tu problemy takie jak czas przełączania wątków, zagłodzenie wątków, wyścigi, synchronizacja itp.

    Jak kolega ma zadanie, które oblicza godzinami pewien algorytm to dam również dwie rady. Sugeruję wpierw zoptymalizować algorytm, a potem spróbować zastosować inny język programowania. Może Erlang?

    0
  • #19 21 Lut 2012 17:52
    leburaque
    Poziom 17  

    Dżyszla napisał:
    ...(najlepiej poszukiwanie metodą bisekcji).

    A to zadanie poważnie jest aż tak skalowalne i nieliniowe?


    Nie znam niestety tej metody. Próbuję właśnie odczytać co to znaczy w przykładzie http://www.matematyka.pl/277923.htm i na wiki http://pl.wikipedia.org/wiki/Metoda_r%C3%B3wnego_podzia%C5%82u

    Nie wiem, czy potrzebuję czegoś skomplikowanego. Potrzebuję jedynie w przybliżeniu ogarnąć gdzie jest magiczna granica wydajności programu.

    Nie wiem jak miałbym wyskalować to zadanie, ale dotyczy ono symulacji komputerowych zachowań ludzkich bliskie paradygmatom Latane-Nowaka. Matryce są wielkości 1000x1000 osób, a program w czasie rzeczywistym przelicza losowe ludzkie zachowania. Jest co liczyć.

    Do dyspozycji będę miał na parę dni farmę komputerów, a więc chciałbym przed odpaleniem symulacji wiedzieć jak mniej więcej poustawiać ilość wątków, aby jak najwięcej danych dostać.

    LED5W napisał:
    Rysowanie powinno być raczej w jednym wątku.
    - założę nowy temat, żeby nie mieszać na forum: https://www.elektroda.pl/rtvforum/viewtopic.php?p=10578284

    sedr napisał:
    Jak kolega ma zadanie, które oblicza godzinami pewien algorytm to dam również dwie rady. Sugeruję wpierw zoptymalizować algorytm, a potem spróbować zastosować inny język programowania. Może Erlang?

    Cóż - nie jestem programistą, tylko psychologiem:). Zadanie mam związane z ponad rocznym projektem badawczym w którym zmagać się muszę dodatkowo z programowaniem. Tak przy okazji - bez rad z Elektrody to bym pewnie długo się męczył:). Kod staram się optymalizować na bieżąco, ale zmieniać języka programowania... na razie nie dam rady:).

    0
  • #20 19 Mar 2012 21:50
    leburaque
    Poziom 17  

    Zauważyłem na koniec dość ciekawą rzecz: miałem do dyspozycji kilkadziesiąt komputerów o identycznych parametrach. Postanowiłem zobaczyć jak szybko pracują w zależności od ilości wątków. Na każdym komputerze ustalałem po prostu o jeden wątek więcej od poprzedniego i starałem się obserwować reakcje i wydajność. Oto spostrzeżenia:

    0) Testy wykonywałem na WinXP i Win7. Wyniki są identyczne. Procesory były czterordzeniowe.
    1) Do ilości wątków równej rdzeniom procesora program przyspiesza wraz z każdym dodanym wątkiem. 2 wątki pracują dokładnie dwa razy szybciej niż jeden, trzy dokładnie trzy razy szybciej niż jeden i tak dalej.
    2) Po przekroczeniu ilości wątków równej ilości rdzeni procesora wydajność programu trzymała się mniej-więcej na stałym poziomie. Kolejny wątek przyspieszał ilość wykonywanych operacji równolegle, ale procesor rozdzielając zadania po prostu nie wyrabiał i spowalniał ogólną pracę wątków.
    3) W efekcie - wątki angażujące procesor ustaliłem do 12 i nie było różnicy w średniej wydajności między 4 a 12. Kiedy menedżer zadań wskazywał maksymalne wykorzystanie procesora, przestało mieć znaczenie ile wątków działa.

    Proszę o krytykę mojej metody badawczej, bo mam wrażenie, że powinno byc nieco inaczej.

    0
  • #21 20 Mar 2012 16:10
    LED5W
    Poziom 32  

    Tak właśnie będzie się zachowywał system. To się nazywa praca z podziałem czasu. ;)

    leburaque napisał:
    Proszę o krytykę mojej metody badawczej, bo mam wrażenie, że powinno byc nieco inaczej.
    Czyli jak?

    0
  • #22 20 Mar 2012 21:20
    leburaque
    Poziom 17  

    Myślałem, że wydajność jest określana w dużo bardziej pokomplikowany sposób. A tu wychodzi, że ilość wątków obciążających procesor do maximum jest po prostu równa ilości rdzeni. Można odpalać następne wątki, tylko po co? :)

    Wcześniej jednak wspominaliśmy tutaj o różnych metodach tworzenia wątków. Więc może zamiast tego - zadam inne pytanie:

    Czy w Delphi jest jakaś procedura pozwalająca stwierdzić ile jest procesorów/rdzeni na maszynie na której pracuje program?

    0
  • Pomocny post
    #23 20 Mar 2012 22:55
    LED5W
    Poziom 32  

    Jeżeli przykładowo jeden z wątków musiałby uzyskać dostęp do dysku to musiałby chwilę zaczekać, a wtedy procesorowi będzie się chwilę nudziło. Chyba, że zajmie go inny wątek.

    Dodatkowo trzeba zwrócić uwagę na ilość rdzeni względem procesorów logicznych. U mnie na i7 (4 rdzenie, 8 procesorów logicznych) uruchomienie 4 wątków, które wykonują pustą pętlę zużywa 50% CPU.

    leburaque napisał:
    Czy w Delphi jest jakaś procedura pozwalająca stwierdzić ile jest procesorów/rdzeni na maszynie na której pracuje program?
    Nawet jeśli nie ma zawsze jest WinAPI. :)

    0
  • #24 21 Mar 2012 18:17
    leburaque
    Poziom 17  

    Dziwne, myślałem, że procesor sam powinien zająć pozostałe procesory logiczne kiedy wykorzysta pełen potencjał podstawowych procesorów... Chyba już nic z tego nie rozumiem.

    Wykrycie procesorów logicznych może być trudne, przypominam, że jestem początkującym programistą. :) Póki co w programie będę szukał po prostu rdzeni (jeśli znajdę jakąś prostą procedurę), ale dodam suwak do "ręcznego" ustalenia wątków. Monitorować sobie zawsze mogę w menedżerze urządzeń - tam widać czy procesor ma full wykorzystania, czy nie:).

    0
  • Pomocny post
    #25 21 Mar 2012 19:34
    LED5W
    Poziom 32  

    leburaque napisał:
    Dziwne, myślałem, że procesor sam powinien zająć pozostałe procesory logiczne kiedy wykorzysta pełen potencjał podstawowych procesorów... Chyba już nic z tego nie rozumiem.
    Zająć czym? :P HT.

    Delphi nie znam. W WinAPI jest funkcja GetLogicalProcessorInformation. Jest nawet ładny przykład.

    0
  • #26 23 Mar 2012 11:14
    leburaque
    Poziom 17  

    Teraz już rozumiem. :)

    Dzięki serdeczne za tę akcję z WinAPI! Poczekam jeszcze z dzień, może w Delphi taka procedura jest gdzieś wbudowana i ktoś da przykład. Jeśli nie - opiszę jak mi poszło.

    0
  Szukaj w 5mln produktów