| Dodaj wpis w tym temacie
Spis tematów | Strona: 1 2 ... 550 551 552 ... 560 561 Wyślij wiadomość do admina |
| Przewiń wpisy ↓ | moje ... oprogramowanie |
2025-03-19 (20:49) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 303 [ CZCIONKA MONOSPACE ] Hejka Wierz lub nie ale początkowo miałem T0.startnew; i kolejne tak samo.. Ale okazało się że nie o to chodzi Otóż gdy wybór to random z 80 to {tasks proces} tak szybko się „odbywa” że między czasy chyba …głupieją Zmieniłem z 80 na 8-mln i już jest lepiej.. Jutro lub pojutrze dalej się przyglądnę temu procesowi to od początku do końca moja procedura Ale mam jeszcze kilka pomysłów na …jej bieg. Ale jesteś szybki👍 Po namyśle usunąłem bo jednak nie widzę tu nikogo kto temat może znać, a fair_play nie pisze w paskalu. |
2025-03-19 (20:59) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 304 [ CZCIONKA MONOSPACE ] Ale dzięki jutro wrócę do startnew 👍 |
2025-03-19 (21:15) kleszekData rejestracji: 2006-05-27 Ilość postów: 4979 | wpis nr 1 558 307 [ CZCIONKA MONOSPACE ] cyt. "dy wybór to random z 80 to {tasks proces} tak szybko się „odbywa” że między czasy chyba …głupieją Zmieniłem z 80 na 8-mln i już jest lepiej.. Odpowiedź chat GPT Gdy zakres losowania jest bardzo mały (80), operacje wykonują się w ułamkach mikrosekundy – czyli czas pomiaru mieści się w granicach rozdzielczości stopera. W rezultacie, nawet minimalne różnice lub opóźnienia systemowe mogą powodować "dziwne" wyniki (czas bliski zeru, ujemne wartości przy konwersji czy zmienne wyniki). Gdy zwiększasz zakres do 8 mln, operacja trwa wystarczająco długo, by stoper mógł zmierzyć czas z większą precyzją, a wyniki stają się wiarygodne. Możliwe rozwiązania: Zwiększ liczbę iteracji: Możesz powielić operację (np. wykonać pętlę wewnątrz zadania wiele razy) tak, aby łączny czas był dłuższy i lepiej mierzalny. Agregacja wyników: Zamiast mierzyć pojedyncze, bardzo szybkie operacje, mierz sumaryczny czas wielu powtórzeń. Upewnij się, że stoper jest poprawnie inicjalizowany: Jak już ustaliliśmy, korzystaj z metody TStopwatch.StartNew, by uniknąć błędów związanych z niezainicjalizowanymi zmiennymi. Podsumowując, problem nie leży w logice zadania, a w fakcie, że mierzymy bardzo krótkie interwały czasowe, które przekraczają dokładność naszego narzędzia. W takich przypadkach warto zwiększyć obciążenie, aby wyniki były bardziej wiarygodne. Po pzeczytaniu usuń te "moje" wpisy. Zakłócają temat moje ... oprogramowanie |
2025-03-19 (22:36) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 325 [ CZCIONKA MONOSPACE ] kleszek chatGPT może być pomocny. Jednak w tym przypadku nie doradził ....... NIC Zrezygnowałem ze stopera. wybór z random 8 mln losowy do skutku ......... do momentu gdy : random1 czyli pierwszy tasks wylosuje liczbę 2 z deklarowanej liczby 8000000 random2 czyli drugi tasks wylosuje liczbę 25 z deklarowanej liczby 8000000 random3 czyli trzeci tasks wylosuje liczbę 39 z deklarowanej liczby 8000000 random4 czyli czwarty tasks wylosuje liczbę 41 z deklarowanej liczby 8000000 oto czasy w milisekundach ..... jak widać -->masa operacji ![]() przy wyborze z 80 liczb ![]() natomiast przy 100 000 Resultat procesu [1] typ=liczba [2] z 100000 /rng/ Czas procesu {Elapsed time1 00:00:00:008} liczba prób = {125954} Resultat procesu [2] typ=liczba [25] z 100000 /rng/ Czas procesu {Elapsed time2 00:00:00:013} liczba prób = {183079} Resultat procesu [3] typ=liczba [39] z 100000 /rng/ Czas procesu {Elapsed time3 00:00:00:008} liczba prób = {244769} Resultat procesu [4] typ=liczba [41] z 100000 /rng/ Czas procesu {Elapsed time4 00:00:00:001} liczba prób = {9323} ----podsumowanie---- Sum wynik: 4/4 liczby typowane Elapsed Time task proces 00:00:00:017 Suma prób dla procesu 4/4 z 100000-liczb = 563125 jak widzisz czasy w okolicach 1~13 milisekund a sumaryczny czas procesu to 17 milisekund a --> człowiek mruga co cirka 400~500 milisekund a tu zrzut z programu dla 100 000 ![]() to tylko testy ,po to aby prawidłowo potasować procedury do tasowania pozdrawiam a użyłem dekodowania czasu w ten sposób: //zaczynamy mierzyć czas start1:= now; //czas pierwszy task //kończymy mierzenie czasu koniec2:= now; //ustalamy różnicę czasu timeDiff2:= koniec2 - start2; //dekodujemy czas na składowe czasu DecodeTime(timeDiff2, hours, minutes, seconds, millisec); //teraz ustalamy sami format zapisu if hours=0 then hgodz:='00' ; if (hours<10)and(hours>0) then hgodz:= '0' + inttostr(hours) ; if hours >= 10 then hgodz:=inttostr(hours); if minutes=0 then hmin:='00' ; if (minutes<10)and(minutes>0) then hmin:='0' + inttostr(minutes); if minutes>=10 then hmin:= inttostr(minutes); if seconds=0 then hsec:='00' ; if (seconds<10)and(seconds>0) then hsec:= '0' +inttostr(seconds) ; if seconds>=10 then hsec:= inttostr(seconds); if millisec=0 then hmilsec:='000'; if (millisec<10)and(millisec>0) then hmilsec:= '00'+inttostr(millisec); if (millisec<100)and(millisec>=10) then hmilsec:= '0'+inttostr(millisec); if millisec>=100 then hmilsec:= inttostr(millisec); upływ_czasu1:= 'Elapsed time1 '+ hgodz+':'+hmin+':'+hsec+':'+hmilsec; //zapisujemy czas trochę długa forma ale za to wynik upływu czasu prawidłowy bo nie -->pracuje prawidłowo na raz 5-stoperów<-- przy szybkich obliczeniach........ |
2025-03-19 (22:48) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 326 [ CZCIONKA MONOSPACE ] a tu test=pula czyli zbiór = 100 mln zadanie polega na wylosowaniu 4 konkretnych liczb zadanie przydzielamy 4-em odrębnym random paskala każdy losuje własną 1 value z value=100mln koniec wtedy gdy: random1 wylosuje value=2 random2 wylosuje value=25 random3 wylosuje value=39 random4 wylosuje value=41 obrazek: ![]() czas całkowity operacji 2 s 186 milisekund w tym czasie wylosowano w sumie 272 mln 700tys 606 liczb aby trafić na 2,25,39,41 z wartości poczatkowej = 100mln |
2025-03-19 (22:56) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 331 [ CZCIONKA MONOSPACE ] Ponieważ to Multihreading, to czasy procesów idą każdy niezależnie ...... a czas procesu nie jest sumą czasów wątków ,tylko czasem całkowitego zakończenia działania aplikacji. Ponieważ nie znam się na tym ,to się muszę pobawić i zrozumieć ...... bo jedni narzekają , a inni chwalą ..... ten sposób przetwarzania danych, niestety wymaga on najlepiej kilku lub wielu rdzeni procesora w komputerze. Multithreading, czyli wielowątkowość, to technika pozwalająca na jednoczesne wykonywanie wielu wątków w ramach jednej aplikacji. Wątek to najmniejsza jednostka wykonawcza, która może być uruchamiana na procesorze. W kontekście multithreadingu, każdy wątek działa niezależnie, ale wszystkie dzielą wspólne zasoby aplikacji, takie jak pamięć czy zmienne globalne. Dzięki temu możliwe jest równoległe przetwarzanie różnych zadań, co pozwala na bardziej efektywne wykorzystanie mocy obliczeniowej procesora. W praktyce procesory nowoczesnych komputerów mają wiele rdzeni (tzw. procesory wielordzeniowe), które pozwalają na wykonywanie wielu wątków równocześnie. Każdy rdzeń może obsługiwać jeden lub więcej wątków, co zwiększa wydajność systemu. |
2025-03-19 (23:06) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 335 [ CZCIONKA MONOSPACE ] A...... co do problemu..... przy wyborze 4*po 1 z 80 liczb czas znalezienia 4* po jednej żądanej liczbie przy procesie na 4 wątki --> nie jest mierzalny w milisekundach raptem 3 milisekundy to czas głównie wypisu jak wcześniej na wstawionym powyżej i poniżej obrazku ![]() --- wpis edytowano 2025-03-19 23:07 --- |
2025-03-20 (08:54) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 357 [ CZCIONKA MONOSPACE ] kleszek Jeśli będziesz miał jakies pytania do AI, mogę je zadać w Twoim imieniu. Jeszcze przez kilka dni mam dostęp "plus" do tej platformy. Poproszę zatem abyś zadał pytanie, dotyczące multithreading delphi object pascal. Mianowicie pytanie brzmi : Podaj przykład procedury obliczeń z użyciem pętli Loop ,z zastosowaniem Multithreadingu w delphi object pascal, dla 32 wątków jednocześnie wykonujących proces obliczeń. Przykład procedury obliczeń , której wynik jest zawsze ten sam, a czas obliczeń jest różny w zależności od ilości rdzeni procesora. Przykładowa procedura działać musi niezależnie od ilości rdzeni. no i ciekaw jestem ..co podpowie AI |
2025-03-20 (09:10) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 361 [ CZCIONKA MONOSPACE ] Instrukcja iteracyjna jest to każda pętla (while, do..while, for) EDIT: Czyli instrukcja powtarzania pewnego zestawu poleceń. Nazwa wzięła się od łacińskiego słowa iteratio, itero ("powtarzanie" w wolnym tłumaczeniu). Iteracja oznacza także pojedyncze wykonanie pętli. --------------------------------------------------- A jak odpowie AI to skompilujemy i zobaczymy co podpowiedziała -------------------------------------------------- A jak odpowie to zadaj podobne pytanie ........ Mianowicie 2-pytanie brzmi : Podaj przykład procedury obliczeń z użyciem kilku instrukcji iteracyjnych ,z zastosowaniem Multithreadingu w delphi object pascal, dla 32 wątków jednocześnie wykonujących proces obliczeń. Przykład procedury obliczeń , której wynik jest zawsze ten sam, a czas obliczeń jest różny w zależności od ilości rdzeni procesora. Przykładowa procedura działać musi niezależnie od ilości rdzeni. pozdrawiam --- wpis edytowano 2025-03-20 09:14 --- |
2025-03-20 (09:41) kleszekData rejestracji: 2006-05-27 Ilość postów: 4979 | wpis nr 1 558 368 [ CZCIONKA MONOSPACE ] 777ch, zrobię to jak wrócę po pracy do domu. Około godziny 14-15 |
2025-03-20 (12:31) MultiTestData rejestracji: 2020-08-05 Ilość postów: 6113 | wpis nr 1 558 391 [ CZCIONKA MONOSPACE ] Tworzymy 32 wątki za pomocą klasy TThread. Każdy wątek wykonuje iteracyjne obliczenia (np. sumowanie wartości z określonego zakresu). Synchronizujemy dostęp do wspólnej zmiennej GlobalSum przy użyciu TInterlocked.Add. Czekamy na zakończenie wszystkich wątków. Mierzymy czas wykonania dla różnych konfiguracji procesora. program MultiThreadedComputation; uses System.SysUtils, System.Classes, System.SyncObjs, System.Diagnostics; const THREAD_COUNT = 32; ITERATIONS = 1000000; // Ilość iteracji w każdym wątku var GlobalSum: Int64; // Globalna zmienna przechowująca wynik końcowy Threads: array [0..THREAD_COUNT - 1] of TThread; Stopwatch: TStopwatch; type TComputeThread = class(TThread) private FThreadID: Integer; protected procedure Execute; override; public constructor Create(ThreadID: Integer); end; constructor TComputeThread.Create(ThreadID: Integer); begin inherited Create(False); // Uruchamiamy wątek natychmiast FreeOnTerminate := False; // Nie usuwamy automatycznie FThreadID := ThreadID; end; procedure TComputeThread.Execute; var LocalSum: Int64; I: Integer; begin LocalSum := 0; for I := 1 to ITERATIONS do begin LocalSum := LocalSum + (I mod 10); // Przykładowe obliczenia end; TInterlocked.Add(GlobalSum, LocalSum); // Atomowe dodanie wyniku end; procedure RunComputation; var I: Integer; begin GlobalSum := 0; // Resetujemy globalny wynik Stopwatch := TStopwatch.StartNew; // Tworzymy i uruchamiamy wątki for I := 0 to THREAD_COUNT - 1 do Threads[I] := TComputeThread.Create(I); // Czekamy na zakończenie wszystkich wątków for I := 0 to THREAD_COUNT - 1 do begin Threads[I].WaitFor; Threads[I].Free; end; Stopwatch.Stop; Writeln('Wynik obliczeń: ', GlobalSum); Writeln('Czas wykonania (ms): ', Stopwatch.ElapsedMilliseconds); end; begin try Writeln('Rozpoczynamy wielowątkowe obliczenia...'); RunComputation; Writeln('Koniec obliczeń.'); except on E: Exception do Writeln('Błąd: ', E.Message); end; Readln; end. Tworzymy 32 wątki – TComputeThread, każdy wykonuje obliczenia w Execute. Każdy wątek iteruje ITERATIONS = 1 000 000 razy, dodając wartości do LocalSum. TInterlocked.Add zapewnia, że operacja dodawania do GlobalSum jest atomowa (unikamy problemów z równoczesnym dostępem do pamięci). Stopwatch mierzy czas wykonania i wynik jest wyświetlany. Właściwości tej implementacji: ✅ Wynik zawsze ten sam – suma z 32 wątków jest zawsze identyczna. ✅ Czas zależny od CPU – na wielordzeniowych CPU wykonuje się szybciej, ale działa również na jednordzeniowych procesorach. ✅ Zastosowanie TInterlocked – zapewnia synchronizację wątków bez potrzeby stosowania krytycznych sekcji (TMonitor, TCriticalSection). ✅ Zgodność z różnymi wersjami Delphi – działa w Delphi XE i nowszych. |
2025-03-20 (13:53) kleszekData rejestracji: 2006-05-27 Ilość postów: 4979 | wpis nr 1 558 403 [ CZCIONKA MONOSPACE ] Pytanie multithreading delphi object pascal Podaj przykład procedury obliczeń z użyciem pętli Loop ,z zastosowaniem Multithreadingu w delphi object pascal, dla 32 wątków jednocześnie wykonujących proces obliczeń. Przykład procedury obliczeń , której wynik jest zawsze ten sam, a czas obliczeń jest różny w zależności od ilości rdzeni procesora. Przykładowa procedura działać musi niezależnie od ilości rdzeni. Odpowiedź Poniżej przedstawiam przykładowy kod w Delphi (Object Pascal), który tworzy 32 wątki – każdy z nich wykonuje pętlę obliczeniową (w tym przykładzie sumuje funkcję sinus w określonym zakresie). Wynik całkowity jest deterministyczny (przy tych samych ustawieniach ITER_COUNT), a czas wykonania zależy od liczby rdzeni procesora, ponieważ wątki będą planowane przez system operacyjny niezależnie od dostępnych rdzeni. procedure MultiThreadedCalculation; const THREAD_COUNT = 32; // liczba wątków ITER_COUNT = 1000000; // liczba iteracji w każdym wątku (można zwiększyć, aby obciążenie było większe) var Threads: array of TThread; Results: array of Double; i: Integer; GlobalResult: Double; begin SetLength(Threads, THREAD_COUNT); SetLength(Results, THREAD_COUNT); // Inicjalizacja wyników dla każdego wątku for i := 0 to THREAD_COUNT - 1 do Results[i] := 0.0; // Tworzenie i uruchamianie wątków for i := 0 to THREAD_COUNT - 1 do begin // Używamy lokalnej zmiennej 'idx', aby zapewnić poprawne przekazanie numeru wątku var idx: Integer; idx := i; Threads[i] := TThread.CreateAnonymousThread( procedure var j: Integer; LocalResult: Double; begin LocalResult := 0.0; // Przykładowe obliczenia – suma wartości Sin(j) for j := 1 to ITER_COUNT do LocalResult := LocalResult + Sin(j); Results[idx] := LocalResult; end ); Threads[i].Start; end; // Oczekiwanie na zakończenie wszystkich wątków for i := 0 to THREAD_COUNT - 1 do Threads[i].WaitFor; // Sumowanie wyników z poszczególnych wątków GlobalResult := 0.0; for i := 0 to THREAD_COUNT - 1 do GlobalResult := GlobalResult + Results[i]; // Wyświetlenie wyniku WriteLn(Format('Wynik obliczeń: %f', [GlobalResult])); end; Kilka uwag: Deterministyczność: Obliczenia (suma sinusa) są deterministyczne – przy tym samym ITER_COUNT wynik będzie zawsze taki sam. Wielowątkowość: Nawet jeśli komputer ma mniej niż 32 rdzenie, procedura utworzy 32 wątki. System operacyjny sam rozplanuje ich wykonanie na dostępnych rdzeniach, co wpłynie na czas obliczeń. Lokalna zmienna 'idx': Dzięki użyciu lokalnej zmiennej 'idx' unikamy problemu zamknięcia (closure) w anonimowej procedurze, co gwarantuje, że każdy wątek zapisze wynik do właściwego elementu tablicy. Przykładowa procedura działa niezależnie od ilości rdzeni – niezależnie od sprzętu, zawsze zostanie uruchomionych 32 wątki, a czas wykonania będzie odzwierciedlał możliwości obliczeniowe komputera. |
2025-03-20 (13:57) kleszekData rejestracji: 2006-05-27 Ilość postów: 4979 | wpis nr 1 558 406 [ CZCIONKA MONOSPACE ] Pytanie 2 Podaj przykład procedury obliczeń z użyciem kilku instrukcji iteracyjnych ,z zastosowaniem Multithreadingu w delphi object pascal, dla 32 wątków jednocześnie wykonujących proces obliczeń. Przykład procedury obliczeń , której wynik jest zawsze ten sam, a czas obliczeń jest różny w zależności od ilości rdzeni procesora. Przykładowa procedura działać musi niezależnie od ilości rdzeni. Odpowiedź Poniżej przykład procedury w Delphi (Object Pascal), w której dla 32 wątków równolegle wykonywane są dwa zestawy iteracyjnych obliczeń. Każdy wątek wykonuje: Pierwszą pętlę – sumuje iloczyn sinusa i cosinusa kolejnych liczb, Drugą pętlę – dodaje logarytm (ln) z wartości (j + 1). Wynik końcowy jest sumą wyników wszystkich wątków. Dzięki temu, mimo że każdy wątek wykonuje te same obliczenia, czas ich wykonania zależy od liczby rdzeni procesora (system sam rozdziela wątki na dostępne rdzenie), a procedura działa niezależnie od ich liczby. procedure MultiThreadedCalculation; const THREAD_COUNT = 32; // liczba wątków ITER1_COUNT = 100000; // liczba iteracji w pierwszej pętli ITER2_COUNT = 50000; // liczba iteracji w drugiej pętli var Threads: array of TThread; Results: array of Double; i: Integer; GlobalResult: Double; begin SetLength(Threads, THREAD_COUNT); SetLength(Results, THREAD_COUNT); for i := 0 to THREAD_COUNT - 1 do Results[i] := 0.0; // Tworzymy i uruchamiamy 32 wątki for i := 0 to THREAD_COUNT - 1 do begin var idx: Integer := i; // zmienna pomocnicza, aby uniknąć problemu zamknięcia (closure) Threads[i] := TThread.CreateAnonymousThread( procedure var j: Integer; LocalResult: Double; begin LocalResult := 0.0; // Pierwsza pętla iteracyjna – obliczenia z użyciem sinusa i cosinusa for j := 1 to ITER1_COUNT do LocalResult := LocalResult + Sin(j) * Cos(j); // Druga pętla iteracyjna – obliczenia z użyciem logarytmu naturalnego for j := 1 to ITER2_COUNT do LocalResult := LocalResult + Ln(j + 1); // Zapis wyniku dla danego wątku Results[idx] := LocalResult; end ); Threads[i].Start; end; // Oczekiwanie na zakończenie wszystkich wątków for i := 0 to THREAD_COUNT - 1 do Threads[i].WaitFor; // Sumujemy wyniki z poszczególnych wątków GlobalResult := 0.0; for i := 0 to THREAD_COUNT - 1 do GlobalResult := GlobalResult + Results[i]; // Wyświetlenie końcowego wyniku WriteLn(Format('Wynik obliczeń: %f', [GlobalResult])); end; Uwagi: Deterministyczność: Obliczenia w każdej pętli są deterministyczne, więc dla ustalonych stałych ITER1_COUNT i ITER2_COUNT wynik końcowy będzie zawsze taki sam. Wielowątkowość: Nawet jeśli komputer ma mniej niż 32 rdzenie, procedura utworzy 32 wątki – system operacyjny rozplanuje ich wykonanie na dostępnych rdzeniach, co wpływa na czas obliczeń. Niezależność od liczby rdzeni: Procedura działa zawsze tak samo, niezależnie od sprzętowych możliwości, a czas wykonania obliczeń zależy jedynie od dostępnych rdzeni procesora. Ten przykład ilustruje, jak wykorzystać multithreading wraz z kilkoma instrukcjami iteracyjnymi w Delphi, aby osiągnąć deterministyczne wyniki przy zmiennym czasie wykonania zależnym od konfiguracji sprzętowej. |
2025-03-20 (14:13) MultiTestData rejestracji: 2020-08-05 Ilość postów: 6113 | wpis nr 1 558 407 [ CZCIONKA MONOSPACE ] To samo pytanie i różne odpowiedzi. Kleszek zadaj to samo jeszcze raz i co otrzymasz ? |
2025-03-20 (14:20) MultiTestData rejestracji: 2020-08-05 Ilość postów: 6113 | wpis nr 1 558 408 [ CZCIONKA MONOSPACE ] Jest jeszcze problem oceny tego co dostajesz, bo w każdej opowiedzi mogą być zawarte bzdury, wyrwane z kontekstu fragmenty cudzych kodów, albo niepasujące do używanej wersji delphi a czasem zupełnie wymyślone Kolejne pytanie czy czat darmowy czy płatny. Przecież ostrzegają na początku, że czat może popełniać błędy A co zwerifikujesz, przecież to nie jest forum programistów. |
2025-03-20 (14:23) MultiTestData rejestracji: 2020-08-05 Ilość postów: 6113 | wpis nr 1 558 410 [ CZCIONKA MONOSPACE ] Pytanie dla Copilota: Podaj przykład procedury obliczeń z użyciem kilku instrukcji iteracyjnych ,z zastosowaniem Multithreadingu w delphi object pascal, dla 32 wątków jednocześnie wykonujących proces obliczeń. Przykład procedury obliczeń , której wynik jest zawsze ten sam, a czas obliczeń jest różny w zależności od ilości rdzeni procesora. Przykładowa procedura działać musi niezależnie od ilości rdzeni. ======================================================= Oto przykład procedury w Delphi Object Pascal, która wykorzystuje 32 wątki do obliczeń. Wynik procedury pozostaje taki sam, niezależnie od liczby rdzeni procesora, ale czas wykonania zależy od dostępnych zasobów sprzętowych. Procedura opiera się na technikach wielowątkowości z użyciem klasy TTask z System.Threading: delphi program MultiThreadExample; uses System.SysUtils, System.Threading; const ThreadCount = 32; function ComputeTask(Index: Integer): Integer; var Sum, I: Integer; begin Sum := 0; for I := 1 to 100000000 do Sum := (Sum + Index) mod 1000; // Prosta iteracyjna operacja obliczeniowa Result := Sum; end; procedure RunMultiThreadedComputation; var Results: array[0..ThreadCount - 1] of Integer; Tasks: array[0..ThreadCount - 1] of ITask; I: Integer; FinalSum: Integer; begin // Tworzymy i uruchamiamy 32 wątki for I := 0 to ThreadCount - 1 do begin Tasks[I] := TTask.Run( procedure begin Results[I] := ComputeTask(I); end ); end; // Oczekiwanie na zakończenie wszystkich wątków TTask.WaitForAll(Tasks); // Zbieranie wyników FinalSum := 0; for I := 0 to ThreadCount - 1 do Inc(FinalSum, Results[I]); Writeln('Final Sum: ', FinalSum); end; begin try Writeln('Starting multi-threaded computation...'); RunMultiThreadedComputation; Writeln('Computation complete.'); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. Wyjaśnienie: Iteracyjne obliczenia: Funkcja ComputeTask wykonuje iteracje, które realizują proste obliczenia. W tym przykładzie, obliczenia zawsze zwracają przewidywalny wynik dla tej samej liczby Index. Wielowątkowość: TTask pozwala na równoległe wykonywanie kodu w niezależnych wątkach. Niezależność od liczby rdzeni: Program uruchamia 32 wątki, niezależnie od liczby rdzeni procesora. Czas wykonania będzie różny w zależności od liczby rdzeni, ale wynik pozostanie spójny. Synchronizacja: TTask.WaitForAll zapewnia, że wszystkie wątki zakończą swoje działanie przed kontynuacją programu. |
2025-03-20 (14:36) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 412 [ CZCIONKA MONOSPACE ] MultiTest No to będzie co sprawdzać na moich 16-rdzeniach. Ale jak to czy tamto skompiluję. Wydaje mi się jednak ,że bardziej skomplikowane procesy obliczeń nie uzyskają jakiejś spektakularnej różnicy w czasie. Jedną z kompilacji ,-->procedura z netu skompilowałem dla 32b a druga dla 64b i jest różnica obliczeń na korzyść 64 oto obrazkowe porównanie ![]() --- wpis edytowano 2025-03-20 14:36 --- |
2025-03-20 (14:43) 777chData rejestracji: 2005-11-07 Ilość postów: 22780 | wpis nr 1 558 416 [ CZCIONKA MONOSPACE ] powyżej to kompilacje tego procesu: unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, system.threading, math; type TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); { TMyThread is the class that will handle our background work } private { Private declarations } public { Public declarations } end; podziałLiczby= array[0..9] of integer; zakresy= array[1..4] of record dół, góra: int64 end; wynik= array[0..9] of record ileCyfr: integer; liczba: int64 end; TYPE MyThread = class(TThread) end; {$R *.dfm} var Form1: TForm1; hczas,hgodz,hmin,hsec,hmilsec:string; ilerdzeni:integer; implementation function podzielNaZakresy(a,b: int64): zakresy; //dzieli zakres pętli for dla rozłożenia na cztery rdzenie procesora var i, iloraz: int64; wynik: zakresy; begin iloraz:= (b-a+1)div 4; for i := 1 to 4 do begin wynik[i].dół:= (i-1)*iloraz+a; if i<4 then wynik[i].góra:= (i-1)*iloraz+a+iloraz-1 else wynik[i].góra:= b; end; result:=wynik end; function rozłóżLiczbę(i: int64):podziałLiczby; //liczy wystąpienia cyfr w liczbie var k,c : integer; s: string; temp: podziałLiczby; begin for k := 0 to 9 do temp[k]:= 0; s:=IntToStr(i); for k:= 0 to 9 do begin c:= StrToInt(s[k+1]); temp[c]:= temp[c]+1; end; result:= temp; end; procedure TForm1.Button1Click(Sender: TObject); var maks: wynik; wynikiRdzeni: array[1..4] of wynik; zakresyRdzeni: zakresy; tasks: array of ITask; i,k: int64; hours, minutes, seconds, millisec: word; start,koniec,timeDiff: tdatetime; begin //ilerdzeni:=MyThread.ProcessorCount.Size; button1.Caption:='Liczba rdzeni: '+inttostr(MyThread.ProcessorCount.Size); start:= now; for i:=0 to 9 do maks[i].ileCyfr:= 0; for i := 1 to 4 do for k := 0 to 9 do wynikiRdzeni[i,k].ileCyfr:=0; Setlength(tasks ,4); zakresyRdzeni:= podzielNaZakresy(1000000000,1800000000); tasks[0]:= TTask.Create (procedure () var temp: podziałLiczby; i,k: int64; begin For i:= zakresyRdzeni[1].dół to zakresyRdzeni[1].góra do begin if sqr(round(sqrt(i))) = i then begin temp:= rozłóżLiczbę(i); for k:= 0 to 9 do if temp[k]> wynikiRdzeni[1,k].ileCyfr then begin wynikiRdzeni[1,k].ileCyfr:= temp[k]; wynikiRdzeni[1,k].liczba:= i end; end; end end); tasks[0].Start; tasks[1]:= TTask.Create (procedure () var temp: podziałLiczby; i,k: int64; begin For i:= zakresyRdzeni[2].dół to zakresyRdzeni[2].góra do begin if sqr(round(sqrt(i))) = i then begin temp:= rozłóżLiczbę(i); for k:= 0 to 9 do if temp[k]> wynikiRdzeni[2,k].ileCyfr then begin wynikiRdzeni[2,k].ileCyfr:= temp[k]; wynikiRdzeni[2,k].liczba:= i end; end; end end); tasks[1].Start; tasks[2]:= TTask.Create (procedure () var temp: podziałLiczby; i,k: int64; begin For i:= zakresyRdzeni[3].dół to zakresyRdzeni[3].góra do begin if sqr(round(sqrt(i))) = i then begin temp:= rozłóżLiczbę(i); for k:= 0 to 9 do if temp[k]> wynikiRdzeni[3,k].ileCyfr then begin wynikiRdzeni[3,k].ileCyfr:= temp[k]; wynikiRdzeni[3,k].liczba:= i end; end; end end); tasks[2].Start; tasks[3]:= TTask.Create (procedure () var temp: podziałLiczby; i,k: int64; begin For i:= zakresyRdzeni[4].dół to zakresyRdzeni[4].góra do begin if sqr(round(sqrt(i))) = i then begin temp:= rozłóżLiczbę(i); for k:= 0 to 9 do if temp[k]> wynikiRdzeni[4,k].ileCyfr then begin wynikiRdzeni[4,k].ileCyfr:= temp[k]; wynikiRdzeni[4,k].liczba:= i end; end; end end); tasks[3].Start; TTask.WaitForAll(tasks); //zbieramy dane z wątków razem for i:= 0 to 9 do for k:=1 to 4 do if wynikiRdzeni[k,i].ileCyfr>maks[i].ileCyfr then begin maks[i].ileCyfr:= wynikiRdzeni[k,i].ileCyfr; maks[i].liczba:= wynikiRdzeni[k,i].liczba end; koniec:= now; timeDiff:= koniec - start; DecodeTime(timeDiff, hours, minutes, seconds, millisec); memo1.Lines.Add('godziny='+IntToStr(hours)); memo1.Lines.Add('minuty='+IntToStr(minutes)); memo1.Lines.Add('sekundy='+IntToStr(seconds)); memo1.Lines.Add('milisekundy='+IntToStr(millisec)); if hours=0 then hgodz:='00' else if (hours<10)and(hours>0) then hgodz:= '0'+IntToStr(hours) else if hours>=10 then hgodz:= IntToStr(hours); if minutes=0 then hmin:='00' else if (minutes<10)and(minutes>0) then hmin:= '0'+IntToStr(minutes) else if minutes>=10 then hmin:= IntToStr(minutes); if seconds=0 then hsec:='00' else if (seconds<10)and(seconds>0) then hsec:= '0'+IntToStr(seconds) else if seconds>=10 then hsec:= IntToStr(seconds); if millisec=0 then hmilsec:='000' else if (millisec<10)and(millisec>0) then hmilsec:= '00'+IntToStr(millisec) else if (millisec<100)and(millisec>=10) then hmilsec:= '0'+IntToStr(millisec) else if millisec>=100 then hmilsec:= IntToStr(millisec); memo1.Lines.Add(''); memo1.Lines.Add('elapsed time: '+ hgodz+' '+hmin+' '+hsec+' '+hmilsec); memo1.Lines.Add(''); for k:= 0 to 9 do if maks[k].ileCyfr > 0 then memo1.Lines.Add('najwięcej cyfr dla '+IntToStr(k)+' wynosi '+ IntToStr(maks[k].ileCyfr)+' dla '+IntToStr(maks[k].liczba)) end; end. ---------------------------------------- To opracowanie z jakiejś strony w necie z drobną modyfikacją. |
2025-03-20 (14:45) MultiTestData rejestracji: 2020-08-05 Ilość postów: 6113 | wpis nr 1 558 417 [ CZCIONKA MONOSPACE ] 64 bitowa kompilacja, większe możliwości, większa wydajność. |
2025-03-20 (14:51) MultiTestData rejestracji: 2020-08-05 Ilość postów: 6113 | wpis nr 1 558 418 [ CZCIONKA MONOSPACE ] ale, jeśli szukać efektywności to nie koniecznie pokrycie może być jedynym środkiem do celu, przecież może być tak, że pokrycie pokaże że jeszcze dużo brakuje, nawet gdy rzeczywista gwarancja będzie 100 % --- wpis edytowano 2025-03-20 14:52 --- |
| | Dodaj wpis w tym temacie | Spis tematów | Wyniki lotto | Strona: 1 2 ... 550 551 552 ... 560 561 Wyślij wiadomość do admina |