Wątek przeniesiony 2023-06-06 12:52 z Inżynieria oprogramowania przez Riddle.

Powtarzalny pomiar wydajność programów i jego porównanie

0

Mam 1000 unikalnych programów wraz z danymi wejściowymi.
Każdy program:

  • potrzebuje określonej ilości pamięci ram np. 500mb, 2gb
  • zawiera od 1 do N zestawów danych wejściowych
  • jest algorytmem referencyjnym pod kątem czasu wykonania
  • działa jedkowątkowo
  • uruchomiony jest w kontenerze
  • posiada jedną lub więcej implementacji w różnych językach programowania (np. program nr. 201 ma impelementacje w Javie i C#)
  • działa na linuxie

Dla każdego z tych programów chciałbym wykonać porównanie pod kątem czasu wykonania obliczeń na zestawie danych.
Jeżeli mam nowy program który chciałbym sprawdzić to czy musi on uruchamiać się na tym samym procesorze czy jest inny sposób pomiaru wydajności? Np. liczba cykli procesora albo instrukcji itd?

  • Czy jeżeli mam dwa różne procesory np. Intel Xeon 2.5Ghz i AMD Epyc 3.0Ghz to czy jedynym sposobem na porównanie wydajności jest wykonanie pomiaru czasu wykonania dla każdego z procesorów?
  • Czy jeżeli mam dwa lub więcej różnych procesorów o różnym obciążeniu np. na klastrze K8S to czy pomiar wydajności jest możliwy?
  • Jak w zasadzie można zmierzyć wydajność CPU względem różnych modeli i czy możliwe jest uruchamianie takich testów na różnych modelach CPU?
  • Czy jedynym sposobem skalowania takich pomiarów jest posiadanie np. 100 maszyn wirtualnych z 100% procesora i tak aby każda była taka sama?
3
Marcin Marcin napisał(a):

Mam 1000 unikalnych programów wraz z danymi wejściowymi.

Jaki sens ma analiza róznych rozwiązań, bo nie kumam.
I jeszcze "dane wejsciowe", czyli zupełnie nieporównywalne koszty ich wczytania, a przy metodzie black box nie do odróżnienia od rdzenia algorytmu.

Nie wierze, że zamiar ma sens, choć przyjmuję 10% szans że może tak, ale nie umiesz wytłumaczyć o co chodzi

0

@AnyKtokolwiek:

Mam 1000 referencyjnych programów oraz będę miał dodatkowo kilka tysięcy innych programów do porównania.

Wyobraź sobie bazę danych gdzie masz 1000 rekordów dla każdego programu. Każdy z tych programów ma n zestawów danych wejściowych. Wiesz że dla rozwiązania referencyjnego programu 205 czas wykonania dla zestawu 1 wynosi 30min, dla zestawu 2 50.3min a dla zestawu 3 1,4min. Masz teraz drugi program który musisz porównać dla tych samych danych wejściowych. Jak porównać czas wykonania pomiędzy różnymi procesorami?

Dane wejściowe mają max 1mb i są wczytywane z linii komend jako standardowe wejście do programu

1

Zdecyduj się 1000 REFERENCYJNYCH programów (btw nie do końca wierzę, ze będzie pewność, że programy 'slave' będą realizowały to samo zagadnienie, np tą samą metodą numeryczną)
czy 1000 zestawów danych

Jak porównać czas wykonania pomiędzy różnymi procesorami?

Znów, co jest zmienną, bo w obu postach zeznajesz rozbieżnie.
Programy w języku X zawsze będą przegrywały na IO o 20%, albo w języku Y będę dawały gigantyczną premię za czynnik Z (sztywne tablice, rozmiar floata, whatever)

Albo będą gigantycznie przegrywały za rozgrzewanie maszyny wirtualnej / GC / cokolwiek. Puszczajac black box EXE nie odróżniasz.

uruchomiony jest w kontenerze

Nie zwiększa to powtarzalności pomiarów

Nadal wątpię w użyteczność 1000 "jakiś" wyników liczbowych bez kontekstu.

0

@AnyKtokolwiek: wyobraź sobie że masz portal typu
https://codeforces.com/
https://www.hackerrank.com/

Portal zawiera 1000 zadań które możesz rozwiązać np. w 30 różnych językach programowania. Każde zadanie posiada swoje testy (od jednego do n) oraz rozwiązania referecyjne będące wzorce czasowym.

Użytkownicy wrzucają na portal swoje kody źródłowe (pomijamy kwestie bezpieczeństwa, zakładamy że kod jest jednowątkowy) i że nie wykonuje żadnych operacyji których mu nie wolno np. wstawek assemblera, instrukcji wektorowych i takich co znacząco zmieniają czas wykoniania.

W jaki sposób zmierzyć czas wykonania programu dla każdego z zadań?

Postawienie maszyn wirtualnych nawet z 100% użycia CPU odpada, gdyż maszyna będzie miała współdzielony cache z innymi maszynami i kilka innych zasobów więc zostają maszyny fizyczne, które mają taką samą konfiguracje.

Pytanie czy da się zrobić inaczej? Liczenie instrukcji procesora też odpada, gdyż programy wykonujące preprocessing wykonają dużo obliczeń na początku a później mogą być szybsze.

Rozwiązanie musi być niezależne od:

  • języka porgramowania
  • architektury (x86-64, ARM, POWER)
1
Marcin Marcin napisał(a):

Mam 1000 unikalnych programów wraz z danymi wejściowymi.

Okej.

Każdy program:

  • potrzebuje określonej ilości pamięci ram np. 500mb, 2gb
  • zawiera od 1 do N zestawów danych wejściowych
  • jest algorytmem referencyjnym pod kątem czasu wykonania

To znaczy?

  • działa jedkowątkowo
  • uruchomiony jest w kontenerze

Fuj.

  • posiada jedną lub więcej implementacji w różnych językach programowania (np. program nr. 201 ma impelementacje w Javie i C#)
  • działa na linuxie

Dla każdego z tych programów chciałbym wykonać porównanie pod kątem czasu wykonania obliczeń na zestawie danych.
Jeżeli mam nowy program który chciałbym sprawdzić to czy musi on uruchamiać się na tym samym procesorze czy jest inny sposób pomiaru wydajności? Np. liczba cykli procesora albo instrukcji itd?

Wydajności czego? CPU, programu czy algorytmu, pamięci, działania całości?

  • Czy jeżeli mam dwa różne procesory np. Intel Xeon 2.5Ghz i AMD Epyc 3.0Ghz to czy jedynym sposobem na porównanie wydajności jest wykonanie pomiaru czasu wykonania dla każdego z procesorów?

Czy porównanie komfortu jazdy Maybachem i Rolls Roycem jest możliwe tylko wykonując jazdę każdym z nich?

  • Czy jeżeli mam dwa lub więcej różnych procesorów o różnym obciążeniu np. na klastrze K8S to czy pomiar wydajności jest możliwy?

Wydajności czego?

  • Jak w zasadzie można zmierzyć wydajność CPU względem różnych modeli i czy możliwe jest uruchamianie takich testów na różnych modelach CPU?

What are CPU benchmarks?

  • Czy jedynym sposobem skalowania takich pomiarów jest posiadanie np. 100 maszyn wirtualnych z 100% procesora i tak aby każda była taka sama?

Nie.

Marcin Marcin napisał(a):

@AnyKtokolwiek: wyobraź sobie że masz portal typu
https://codeforces.com/
https://www.hackerrank.com/

Portal zawiera 1000 zadań które możesz rozwiązać np. w 30 różnych językach programowania. Każde zadanie posiada swoje testy (od jednego do n) oraz rozwiązania referecyjne będące wzorce czasowym.

Użytkownicy wrzucają na portal swoje kody źródłowe (pomijamy kwestie bezpieczeństwa, zakładamy że kod jest jednowątkowy) i że nie wykonuje żadnych operacyji których mu nie wolno np. wstawek assemblera, instrukcji wektorowych i takich co znacząco zmieniają czas wykoniania.

W jaki sposób zmierzyć czas wykonania programu dla każdego z zadań?

time(1) - nie time budowany w bash

a jeszcze lepiej

perf stat

Uruchomione z najwyższymi priorytetami np przez chrt. Pomijamy tutaj kwestie czy to bezpieczne i jak to się zachowa jak ktoś zcznie testować forkbomby na tym.

Postawienie maszyn wirtualnych nawet z 100% użycia CPU odpada, gdyż maszyna będzie miała współdzielony cache z innymi maszynami i kilka innych zasobów więc zostają maszyny fizyczne, które mają taką samą konfiguracje.

Pytanie czy da się zrobić inaczej? Liczenie instrukcji procesora też odpada, gdyż programy wykonujące preprocessing wykonają dużo obliczeń na początku a później mogą być szybsze.

Inaczej niż co konkretnie?

Rozwiązanie musi być niezależne od:

  • języka porgramowania

time(1)
perf stat

  • architektury (x86-64, ARM, POWER)

W jakim sensie? Każda architektura to inny świat i innaczej wykonuje wiele rzeczy.

0
Satanistyczny Awatar napisał(a):
Marcin Marcin napisał(a):

Mam 1000 unikalnych programów wraz z danymi wejściowymi.

Okej.

Każdy program:

  • potrzebuje określonej ilości pamięci ram np. 500mb, 2gb
  • zawiera od 1 do N zestawów danych wejściowych
  • jest algorytmem referencyjnym pod kątem czasu wykonania

To znaczy?

Każdy program działa z limitem pamięci np. 500mb lub 2gb

  • działa jedkowątkowo
  • uruchomiony jest w kontenerze

Fuj.

Programy nie tworzą wątków.

  • posiada jedną lub więcej implementacji w różnych językach programowania (np. program nr. 201 ma impelementacje w Javie i C#)
  • działa na linuxie

Dla każdego z tych programów chciałbym wykonać porównanie pod kątem czasu wykonania obliczeń na zestawie danych.
Jeżeli mam nowy program który chciałbym sprawdzić to czy musi on uruchamiać się na tym samym procesorze czy jest inny sposób pomiaru wydajności? Np. liczba cykli procesora albo instrukcji itd?

Wydajności czego? CPU, programu czy algorytmu, pamięci, działania całości?

Wydajność od momentu wczytania danych wejściowych jako program konsolowy na stdin a otrzymaniu wyniku na stdout

  • Czy jeżeli mam dwa różne procesory np. Intel Xeon 2.5Ghz i AMD Epyc 3.0Ghz to czy jedynym sposobem na porównanie wydajności jest wykonanie pomiaru czasu wykonania dla każdego z procesorów?

Czy porównanie komfortu jazdy Maybachem i Rolls Roycem jest możliwe tylko wykonując jazdę każdym z nich?

Jeżeli można zrobić benchmark pytanie jak porównać dwa procesory?

  • Czy jeżeli mam dwa lub więcej różnych procesorów o różnym obciążeniu np. na klastrze K8S to czy pomiar wydajności jest możliwy?

Wydajności czego?

Każdego z programów. Czas obliczeń od momentu wczytania danych przez stdin a otrzymania wyniku na stdout jak w aplikacji konsolowej

  • Jak w zasadzie można zmierzyć wydajność CPU względem różnych modeli i czy możliwe jest uruchamianie takich testów na różnych modelach CPU?

What are CPU benchmarks?

Czy sugerujesz wykonanie benchmarku dla każdego programu na każdym procesorze dla programu wzorcowego a następnie porównanie wyników z innymi procesorami?

  • Czy jedynym sposobem skalowania takich pomiarów jest posiadanie np. 100 maszyn wirtualnych z 100% procesora i tak aby każda była taka sama?

Nie.

Jakie są pozostałe? Kilkanaście fizycznych maszyn?

Marcin Marcin napisał(a):

@AnyKtokolwiek: wyobraź sobie że masz portal typu
https://codeforces.com/
https://www.hackerrank.com/

Portal zawiera 1000 zadań które możesz rozwiązać np. w 30 różnych językach programowania. Każde zadanie posiada swoje testy (od jednego do n) oraz rozwiązania referecyjne będące wzorce czasowym.

Użytkownicy wrzucają na portal swoje kody źródłowe (pomijamy kwestie bezpieczeństwa, zakładamy że kod jest jednowątkowy) i że nie wykonuje żadnych operacyji których mu nie wolno np. wstawek assemblera, instrukcji wektorowych i takich co znacząco zmieniają czas wykoniania.

W jaki sposób zmierzyć czas wykonania programu dla każdego z zadań?

time(1) - nie time budowany w bash

a jeszcze lepiej

perf stat

Uruchomione z najwyższymi priorytetami np przez chrt. Pomijamy tutaj kwestie czy to bezpieczne i jak to się zachowa jak ktoś zcznie testować forkbomby na tym.

W jaki sposób priorytetyzacja wypłynie na czas wykonania?

Postawienie maszyn wirtualnych nawet z 100% użycia CPU odpada, gdyż maszyna będzie miała współdzielony cache z innymi maszynami i kilka innych zasobów więc zostają maszyny fizyczne, które mają taką samą konfiguracje.

Pytanie czy da się zrobić inaczej? Liczenie instrukcji procesora też odpada, gdyż programy wykonujące preprocessing wykonają dużo obliczeń na początku a później mogą być szybsze.

Inaczej niż co konkretnie?

Inaczej niż liczenie instrukcji procesora lub czasu pomiędzy wczytaniem danych przez stdin a otrzymaniem wyniku na stdout

Rozwiązanie musi być niezależne od:

  • języka porgramowania

time(1)
perf stat

  • architektury (x86-64, ARM, POWER)

W jakim sensie? Każda architektura to inny świat i innaczej wykonuje wiele rzeczy.

Architektura może inna ale pytanie czy jeżeli kod jest możliwy do uruchomienia na wielu architekturach to czy wydajność jest możliwa do porównania w sposób powtarzalny?

1

Dokumentacja procesorów i man pages odpowiedzą ci na te pytania.

3

Np. liczba cykli procesora albo instrukcji itd

perf stat <program>

Poda Ci liczbę cykli CPU, liczbę instrukcji plus parę innych ciekawych rzeczy.

Ponadto przydaje się też /usr/bin/time -v np. do określenia maksymalnego zużycia pamięci.

0

@Krolik: Dziękuję za włączenie się i podanie przykładu. Czy jeżeli program podczas uruchomienia wykonuje preprocessing danych np. przygotowuje dużą tablicę i wykonuje bardzo dużo obliczeń a później od momentu wczytania danych na stdin do momentu wyplucia danych na stdout wykonuje te obliczenia bardzo szybko to czy można takich pomiarów dokonać?

0
Marcin Marcin napisał(a):

@Krolik: Dziękuję za włączenie się i podanie przykładu. Czy jeżeli program podczas uruchomienia wykonuje preprocessing danych np. przygotowuje dużą tablicę i wykonuje bardzo dużo obliczeń a później od momentu wczytania danych na stdin do momentu wyplucia danych na stdout wykonuje te obliczenia bardzo szybko to czy można takich pomiarów dokonać?

Ten przykład masz w man, dalej nawet nie zajrzałeś? Tu jest wersja online jak co.
https://man7.org/linux/man-pages/man1/time.1.html
https://man7.org/linux/man-pages/man1/perf-stat.1.html

2
Marcin Marcin napisał(a):

@Krolik: Dziękuję za włączenie się i podanie przykładu. Czy jeżeli program podczas uruchomienia wykonuje preprocessing danych np. przygotowuje dużą tablicę i wykonuje bardzo dużo obliczeń a później od momentu wczytania danych na stdin do momentu wyplucia danych na stdout wykonuje te obliczenia bardzo szybko to czy można takich pomiarów dokonać?

Nie do końca wiem jak to robi - ale JMH tak działa (javowy framework do benchmarków) - odpala konkretną funkcję i podaje staty (cpu counters - perf) dla tej funkcji (iluś wywołań). Z tym, że nawet nie wiem na ile jest to dokładne - choć wyniki są dość powtarzalne i wydają się sensowne.

2
jarekr000000 napisał(a):

Nie do końca wiem jak to robi - ale JMH tak działa (javowy framework do benchmarków) - odpala konkretną funkcję i podaje staty (cpu counters - perf) dla tej funkcji (iluś wywołań). Z tym, że nawet nie wiem na ile jest to dokładne - choć wyniki są dość powtarzalne i wydają się sensowne.

Wysokiej jakosci benchmark adekwatny do platformy, dla mnie jak najbardziej OK - tylko to jest coś, czego OP odmawia

0
AnyKtokolwiek napisał(a):
jarekr000000 napisał(a):

Nie do końca wiem jak to robi - ale JMH tak działa (javowy framework do benchmarków) - odpala konkretną funkcję i podaje staty (cpu counters - perf) dla tej funkcji (iluś wywołań). Z tym, że nawet nie wiem na ile jest to dokładne - choć wyniki są dość powtarzalne i wydają się sensowne.

Wysokiej jakosci benchmark adekwatny do platformy, dla mnie jak najbardziej OK - tylko to jest coś, czego OP odmawia

Niestety musi być niezależne od platformy i liczyć czas pomiędzy wczytaniem na stdin a wypluciem danych na stdout

w przypadku platformy byłoby życie za łatwe, trzeba je sobie utrudnić - nawet jest na to przypadek "samoutrudnianie"

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