Aktualności:

Nowy polski projekt BOINC - Universe@Home

Menu główne

trudniejszy przykład

Zaczęty przez mariotti, 24 Lipiec 2013, 07:10

mariotti

Jakie zadanie proponujecie na następny test? Program upper-case był dobry
do sprawdzenia czy serwer w ogóle działa. Teraz by się przydało coś ciut trudniejszego
do policzenia. Tak żeby można było po zakończeniu obliczeń podsumować wyniki i
sprawdzić czy wszystko się zgadza. Jednocześnie zadanie nie może być zbyt
trudne w implementacji.

Pozdrawiam

Dario666

Wyznaczanie liczby PI z coraz większą dokładnością

mariotti

Cytat: Dario666 w 24 Lipiec 2013, 08:15
Wyznaczanie liczby PI z coraz większą dokładnością
Jakim algorytmem?

Pozdrawiam

mariotti

Cytat: mariotti w 24 Lipiec 2013, 08:27
Cytat: Dario666 w 24 Lipiec 2013, 08:15
Wyznaczanie liczby PI z coraz większą dokładnością
Jakim algorytmem?
Może być taki? :D

#include <cstring>
#include <gmp.h>
#include <cstdio>
#include <cassert>
#include <cstdlib>

struct Args {
int   prec;
char *start;
char *stop;
char *r;
};

static Args args;

void help() {
printf("using:gmp_pi prec=int steps=int start=float stop=float r=float\n");
abort();
}

void parseArgs( const int argc , char *argv[] ) {
memset( &args , 0 , sizeof(args) );
for( int i=1 ; i<argc ; i++ ) {
if( strncmp( argv[i] , "prec="  , 5 ) == 0 ) args.prec  = atoi( argv[i]+5 );
if( strncmp( argv[i] , "start=" , 6 ) == 0 ) args.start = strdup( argv[i]+6 );
if( strncmp( argv[i] , "stop="  , 5 ) == 0 ) args.stop  = strdup( argv[i]+5 );
if( strncmp( argv[i] , "r="     , 2 ) == 0 ) args.r     = strdup( argv[i]+2 );
}
if( ! args.r     ) help();
if( ! args.start ) help();
if( ! args.stop  ) help();
}

enum MPZ {
MP_START,
MP_STOP,
MP_R,
MP_OUT,
MP_TMP,
MP_SIZE
};

#define PRINT( __idx__ )  printf( #__idx__ ":" ); mpz_out_str(stdout,10,mpz[__idx__]); printf("\n")

int main( int argc , char *argv[] ) {
int test;
parseArgs( argc , argv );
mpz_t mpz[MP_SIZE];

for( int i=0 ; i<MP_SIZE ; i++ ) mpz_init2( mpz[i] , args.prec );

test = mpz_set_str( mpz[MP_R] , args.r , 10 );
assert( test==0 );
mpz_mul( mpz[MP_R] , mpz[MP_R] , mpz[MP_R] );
test = mpz_set_str( mpz[MP_START] , args.start , 10 );
assert( test==0 );
test = mpz_set_str( mpz[MP_STOP] , args.stop , 10 );
assert( test==0 );

while( mpz_cmp(mpz[MP_START],mpz[MP_STOP]) <= 0 ) {
mpz_mul( mpz[MP_TMP] , mpz[MP_START] ,  mpz[MP_START] );
mpz_sub( mpz[MP_TMP] , mpz[MP_R] , mpz[MP_TMP] );
mpz_sqrt( mpz[MP_TMP] , mpz[MP_TMP] );
mpz_add( mpz[MP_OUT] , mpz[MP_OUT] , mpz[MP_TMP] );
// PRINT(MP_START);
mpz_add_ui( mpz[MP_START] , mpz[MP_START] , 1 );
}
mpz_mul_ui( mpz[MP_OUT] , mpz[MP_OUT] , 4 );

PRINT(MP_OUT);
for( int i=0 ; i<MP_SIZE ; i++ ) mpz_clear( mpz[i] );

return 0;

}


Pozdrawiam

Dario666

Wykonuje podstawowe operacje arytmetyczne, ale ważne, że można sprawdzić czy obliczenia sa prawidłowe. Ewentualnie każde zadanie zdublować jak to robia projekty standardowo :)

mariotti

Cytat: Dario666 w 24 Lipiec 2013, 14:44
Wykonuje podstawowe operacje arytmetyczne, ale ważne, że można sprawdzić czy obliczenia sa prawidłowe. Ewentualnie każde zadanie zdublować jak to robia projekty standardowo :)
Nom tak będzie trzeba zrobić. Ile mam dać taksów i ile średnio czasu ma trwać jeden task?
Pozdrawiam

Rysiu

#6
Taski najlepiej aby były tworzone w mierę potrzeb. Nie wszystkie jednocześnie do bazy ale po części (ale to z czasem można dorobić).

Czas jednego zadania to jakoś kilka godzin. Ustaw na 5 godzin i będzie git.

Cytat: mariotti w 24 Lipiec 2013, 07:10
Jakie zadanie proponujecie na następny test? Program upper-case był dobry
do sprawdzenia czy serwer w ogóle działa. Teraz by się przydało coś ciut trudniejszego
do policzenia. Tak żeby można było po zakończeniu obliczeń podsumować wyniki i
sprawdzić czy wszystko się zgadza. Jednocześnie zadanie nie może być zbyt
trudne w implementacji.

Pozdrawiam
Jak to jaki? Teraz chyba już Twój algorytm.

Lepiej sobie darować Pi (przecież i tak wszyscy będą liczyć do tej samej precyzji) itp. co tylko będą marnować moc obliczeniową.

Karlik

Co do długości trwania to zależy jakie będziesz miał checkpointy. Tak zapis co 0,2h-1h powinien być chyba ok, wtedy długość próbki może być taka jak Rysiu podał - z 5h (w zasadzie dowolna, ale bez przeginania w żadną ze stron - no chyba, że się nie da inaczej - np. długie LLRy z PG).

mariotti

#8
Cytat: Rysiu w 24 Lipiec 2013, 15:21
Taski najlepiej aby były tworzone w mierę potrzeb. Nie wszystkie jednocześnie do bazy ale po
części (ale to z czasem można dorobić).
Hmmm. Zależy od projektu. W programie perft chcemy znać ilość węzłów, więc
teoretycznie wystarczy każdy pod-układ przeliczyć i uaktualniać sumę. Więc
ani na dysku, ani w bazie nie musi być dużo układów - tylko trochę aby nimi karmić
aplikacje liczące. Z drugiej strony pod-układy często się powtarzają, dlatego
wcześniej zadałem sobie trochę trudu z tym algorytmem sort-uniq-sort. Aby
usunąć powtarzające, to trzeba najpierw wygenerować wszystkie. Ponadto
chcę zrobić taką prezentację wyników, która każdemu w dowolny sposób
(nie tylko za pośrednictwem platformy boinc) umożliwi weryfikację wyników.
Prezentacja ta też będzie wymagała aby wszystkie dane były przygotowane
odgórnie. Więc dane i tak i tak muszą leżeć gdzieś na dysku, a nawet powinny
być jakoś zaindeksowane w bazie danych, żeby prezentacja była efektywna.

Idealnie było by tak:
1) generujemy dane
2) przekierowujemy do sort-uniq-sort, a tym samym optymalizujemy
3) zapisujemy zoptymalizowane w bazie danych
4) przechwytujemy zdarzenie downloadu
  a) program odczytuje n układów z bazy
  b) kompresuje układy do zpia
  c) zapisuje na dysku jedno zadanie
  d) zadanie także dopisuje do bazy, do zadań podanych
  e) apache podaje paczkę do aplikacji liczącej

Niemniej taki scenariusz choć jest do osiągnięcia, to prawdopodobnie będzie
bardzo pracochłonny.  Raczej zastosuję dużo prostsze rozwiązanie:
  a) optymalizacja przy pomocy sort-uniq-sort
  b) podział na porcje po N układów
  c) dodanie każdej porcji do tego drzewka w katalogu download
  d) dodanie podwójnej ilości tasków do bazy, każdy task będzie z innym random-seed
  e) utworzenie tabeli układów
  f) od czasu do czasu odświeżanie tabeli układów, no i prezentacja częściowych
      wyników na www

Cytat: Rysiu w 24 Lipiec 2013, 15:21
Czas jednego zadania to jakoś kilka godzin. Ustaw na 5 godzin i będzie git.
Generalnie im dłuższy task, tym krótszy sumaryczny czas obliczeń. W jednym tasku będzie
wiele "sąsiednich" układów. W sąsiednich układach często powtarzają się pod-układy.
Powtórzenia oznaczają możliwość odczytania wyników z pamięci, zamiast czasochłonnych
obliczeń.  Dłuższy czas obliczeń oznacza także lepszą kompresję i mniejszy sumaryczny
transfer. Myślę że po przyspieszeniu programu, całkiem dobra wartość będzie w
granicach od 30minut do 10godzin - nie wiem, zobaczymy.

Bardziej martwi mnie to, że menadżer BOINC uruchamia kilka tasków równolegle. To
samo tyczy się przydziału zasobów dla innych projektów. Weźmy dwie różne strategie
przydziału zasobów:
1) użytkownik podpina się np. do 3 projektów, w tym także do perft'a, a menadżer przez
    całą dobę liczy 6 zadań równolegle w tym np. 2 zadania perfta - rozdziela zasoby
    mniej-więcej po równo,
2) menadżer na 4 godziny w ciągu doby zatrzymuje wszystkie projekty i całe zasoby
    przypisuje do jednego tasku perft
Zarówno pierwsza jaki i druga strategia daje projektowi perft średnio 4h na dobę. Jednak
na tej drugiej strategii sumaryczny czas obliczeń będzie wielokrotnie krótszy, może nawet 5cio
krotnie.


Cytat: Rysiu w 24 Lipiec 2013, 15:21
Jak to jaki? Teraz chyba już Twój algorytm.
Myślę nad całkowitym oddzieleniem kodu boinc od kodu swojej aplikacji. Zoptymalizowany
program do liczenia testu perft jest bardzo skomplikowany, zależy mi na uproszczeniu
kodu. Program perft będzie ewoluował. Docelowo to będzie aplikacja grająca w szachy, ale
będzie też miała implementację algorytmów uczących, może uczenie będzie w oparciu o
platformę BOINC, pewnie interfejs graficzny do gry w szachy zaimplementuję, może dodam
jakąś bazę partii... Jednym słowem perft rozrośnie się do sporego i skomplikowanego
kombajnu. Jeśli bezpośrednio w perft nie będzie kodu BOINC, to znacznie uprości
implementację. Poza tym fajnie byłoby, jakby test perft był zupełnie niezależnym programem,
żeby każdy mógł go pobrać z sieci, ręcznie uruchomić i policzyć węzły - chociażby w
celu dodatkowej weryfikacji.

W związku z powyższym, myślę o stworzeniu dodatkowej aplikacji, która będzie pośredniczyła
pomiędzy nadchodzącymi taskami a programem perft. Więc może dla treningu napiszę najpierw
taki pośrednik dla problemu PI?  Gdy taki pośrednik będzie już dobrze współpracował z BOINC API, to
tylko się przerobi sposób podawania danych na wejście innego programu. Co myślicie o czymś takim?


Cytat: Rysiu w 24 Lipiec 2013, 15:21
Lepiej sobie darować Pi (przecież i tak wszyscy będą liczyć do tej samej precyzji) itp. co tylko będą marnować moc obliczeniową.
To tylko do testów, np. 50 zadań po 30 minut. A precyzja...  sam nie wiem jaką precyzję taki
algorytm może uzyskać. To metoda całkowania trapezami. U mnie na kompie, tamten algorytm
co powyżej wkleiłem kod, w 1h liczy z dokładnością do około 14 cyfr. Szykuje mi się dłuższy
wyjazd, to zostawię go na dwie doby :)

Pozdrawiam

mariotti

Cytat: Karlik w 24 Lipiec 2013, 15:29
Co do długości trwania to zależy jakie będziesz miał checkpointy. Tak zapis co 0,2h-1h powinien być chyba ok, wtedy długość próbki może być taka jak Rysiu podał - z 5h (w zasadzie dowolna, ale bez przeginania w żadną ze stron - no chyba, że się nie da inaczej - np. długie LLRy z PG).
W tym zadaniu check-pionts można zrealizować na wiele sposobów. Właściwie to nie trzeba niczego
zapisywać o ukończonych etapach. Wystarczy dobra heurystyka do rozstrzygania który układ
ma zostać w ram, a który wywalić. W razie przedwczesnego zakończenia aplikacji, RAM z
układami leci na dysk. Po starcie aplikacji odwrotnie: układy są wczytywane z dysku do RAM. Coś w rodzaju
(pół)trwałej tablicy z częściowymi wynikami. Przy takim rozwiązaniu aplikacja może dostawać
tylko jeden układ do policzenia, bo tablica z wynikami częściowymi będzie przechowywana zawsze
na dysku. Niestety jakby aplikacja dostawała po jednym układzie, to musiałyby to być układy
sekwencyjne. Serwer musiałby pamiętać który układ był wysłany do którego komputera i
podawać (o ile to tylko możliwe) sekwencyjne. Zaletą byłby bardzo krótki czas jednego
tasku. Na depth=10 liczyliśmy kilka godzin. Jakby task był na depth=8 to już sto razy
szybciej. Jakby aplikacja była zoptymalizowana - to tysiąc razy szybciej. Jeden taks mógłby
trwać 15 sekund - ale to raczej fantazje - bo za dużo komplikacji z wykonaniem. Raczej
upakuje się kilkadziesiąt - kilkaset układów do jednego zadania.
15 sekund * 250 układów ~ 1h na zadanie.


Analizując dalej... paczki z dużą ilością układów też są złe, bo ta duża ilość układów będzie
liczona na tym samym random-seed. Idealnie byłoby gdyby każdy układ miał inny seed -
niestety wtedy nie zadziała zapamiętywanie powtórzonych układów. Dobierzemy tę
ilość eksperymentalnie.


Pozdrawiam


Karlik

Z checkpointami chodziło mi bardziej o rozwiązanie: "zapisuję sobie co jakiś czas co policzyłem/liczę" - chodzi o to, żeby przy nieoczekiwanym zamknięciu aplikacji (brak prądu, zwis systemu, wstrzymanie zadania bez zachowania w pamięci) móc wznowić od pewnego etapu a nie liczyć znowu od zera.

Jeżeli twierdzisz, że im dłuższe taski tym lepiej to może zrób jak w rosetce czyli pozwól wybierać rozmiar paczek użytkownikowi (to pasuje do tego Twojego pomysłu z dynamicznym generowaniem zadań - pobierz n układów i wyślij klientowi - oczywiście dobierz kilka wartości n do wyboru, żeby móc te zadania wygenerować wcześniej - żeby mieć zapas).

Co do wrappera to chyba nie ma sensu, żebyś pisał go do aplikacji liczącej PI. Masz działający perft to od razu pisz wrapper do niego, dla testów dając jakieś małe głębokości.

Nie do końca rozumiem co masz na myśli z tym przydziałem zasobów - BOINC uruchamia tyle zadań na ile mu pozwala użytkownik (domyślnie tyle ile rdzeni). Jeżeli chodzi Ci o liczenie na wielu wątkach to po prostu daj zadanie wykorzystujące kilka CPU (też możesz to sparametryzować). Domyślnie wszystkie aplikacje BOINC są traktowane jako jednowątkowe.

mariotti

Cytat: Karlik w 26 Lipiec 2013, 02:21
Z checkpointami chodziło mi bardziej o rozwiązanie: "zapisuję sobie co jakiś czas co policzyłem/liczę" - chodzi o to, żeby przy nieoczekiwanym zamknięciu aplikacji (brak prądu, zwis systemu, wstrzymanie zadania bez zachowania w pamięci) móc wznowić od pewnego etapu a nie liczyć znowu od zera.
I właśnie tak Ciebie zrozumiałem. Mnie z kolei chodziło o to, że w przypadku testu perft istnieje
lepsze rozwiązanie. Czasami można zrobić checkpoint także dla tych obliczeń, które będą
wykonywane dopiero w przyszłości :D


Cytat: Karlik w 26 Lipiec 2013, 02:21
Jeżeli twierdzisz, że im dłuższe taski tym lepiej to może zrób jak w rosetce czyli pozwól wybierać rozmiar paczek użytkownikowi (to pasuje do tego Twojego pomysłu z dynamicznym generowaniem zadań - pobierz n układów i wyślij klientowi - oczywiście dobierz kilka wartości n do wyboru, żeby móc te zadania wygenerować wcześniej - żeby mieć zapas).
Nigdzie w menadżerze nie znalazłem możliwości wyboru rozmiaru paczek. Jak
to zrobić, żeby użytkownik mógł wybierać?


Cytat: Karlik w 26 Lipiec 2013, 02:21
Co do wrappera to chyba nie ma sensu, żebyś pisał go do aplikacji liczącej PI. Masz działający perft to od razu pisz wrapper do niego, dla testów dając jakieś małe głębokości.
Jest w tym dużo racji, chyba odpuszczę PI.


Cytat: Karlik w 26 Lipiec 2013, 02:21
Nie do końca rozumiem co masz na myśli z tym przydziałem zasobów -
Nie tak łatwo zgrabnie to opisać....

Pewne są dwie rzeczy:
1) równoległe liczenie dwóch tasków z projektu perft na tej samej maszynie nie ma najmniejszego sensu;
2) równoległe liczenie testu perft z innymi aplikacjami które lubią dużo ram nie ma sensu,
     trzeba je uruchamiać na przemian.

Cytat: Karlik w 26 Lipiec 2013, 02:21
BOINC uruchamia tyle zadań na ile mu pozwala użytkownik (domyślnie tyle ile rdzeni).
Czy da się ustawić zakaz równoległego liczenia dwóch tasków tego samego
projektu na jednym komputerze? Jeśli użytkownik zdecyduje się liczyć perft na dwóch
rdzeniach, to po prostu aplikacja powinna się uruchomić jako dwu-wątkowa.

Cytat: Karlik w 26 Lipiec 2013, 02:21
Jeżeli chodzi Ci o liczenie na wielu wątkach to po prostu daj zadanie wykorzystujące kilka
CPU (też możesz to sparametryzować). Domyślnie wszystkie aplikacje BOINC są traktowane jako jednowątkowe.
Nie ma czegoś takiego w teście perft. Po prostu są zadania. Użytkownik może zadania policzyć
na tylu rdzeniach na ilu chce. Może liczyć na jednym rdzeniu, a może na tysiącu jak ma
super-komputer. Za to zdecydowanie nie powinien liczyć osobnego tasku na każdym rdzeniu.

Pozdrawiam

Karlik

Cytat: mariotti w 28 Lipiec 2013, 19:44
Nigdzie w menadżerze nie znalazłem możliwości wyboru rozmiaru paczek. Jak to zrobić, żeby użytkownik mógł wybierać?
Przypuszczam, że może być wymagana "ręczna" ingerencja w serwer BOINCa, nigdy czegoś takiego nie konfigurowałem, ale widziałem, że się da.
Cytat: mariotti w 28 Lipiec 2013, 19:44
Czy da się ustawić zakaz równoległego liczenia dwóch tasków tego samego
projektu na jednym komputerze?
Da się, tak np. robi wu-prop, że wysyła do klienta tylko jeden task w danym momencie, ale raczej nie polecałbym takiego rozwiązania. Teraz w configach coś pododawali, więc może da się ograniczyć tylko liczbę przeliczanych (a nie dostarczonych tasków). Po stronie klienta chyba jest coś typu max_concurrent.
Cytat: mariotti w 28 Lipiec 2013, 19:44
Nie ma czegoś takiego w teście perft. Po prostu są zadania. Użytkownik może zadania policzyć
na tylu rdzeniach na ilu chce. Może liczyć na jednym rdzeniu, a może na tysiącu jak ma
super-komputer. Za to zdecydowanie nie powinien liczyć osobnego tasku na każdym rdzeniu.
Nie zrozumiałeś mojej intencji. Każde zadanie wysyłane do klienta ma (poza innymi parametrami) dwie liczby: liczbę wykorzystywanych rdzeni CPU oraz GPU (od jakichś ułamkowych wartości - typu 0.01 do normalnych 1 czy 2). Więc jak wyślesz zadanie (sparametryzowane jak wzpominałem wcześniej), które chcesz uruchomić na dwóch rdzeniach to tylko informujesz klienta, że ma zarezerwować dwa rdzenie (wtedy na 4 rdzeniach będą działały np. dwa zwykłe zadania innych projektów i jedno Twoje).
EDIT:
jak piszę o rdzeniach to mam na myśli samodzielną jednostkę obliczeniową, bo rdzenie w wypadku GPU to chyba nie jest najszczęśliwsze określenie  ;)

mariotti

#13
Cytat: Karlik w 28 Lipiec 2013, 21:17
Da się, tak np. robi wu-prop, że wysyła do klienta tylko jeden task w danym momencie, ale raczej nie polecałbym takiego rozwiązania. Teraz w configach coś pododawali, więc może da się ograniczyć tylko liczbę przeliczanych (a nie dostarczonych tasków). Po stronie klienta chyba jest coś typu max_concurrent.
Ok, to będę szukał. Ta blokada jest bardzo ważna.

Cytat: Karlik w 28 Lipiec 2013, 21:17
Nie zrozumiałeś mojej intencji. Każde zadanie wysyłane do klienta ma (poza innymi parametrami) dwie liczby: liczbę wykorzystywanych rdzeni CPU oraz GPU (od jakichś ułamkowych wartości - typu 0.01 do normalnych 1 czy 2). Więc jak wyślesz zadanie (sparametryzowane jak wzpominałem wcześniej), które chcesz uruchomić na dwóch rdzeniach to tylko informujesz klienta, że ma zarezerwować dwa rdzenie (wtedy na 4 rdzeniach będą działały np. dwa zwykłe zadania innych projektów i jedno Twoje).
Zrozumiałem. Problem w tym, że liczy się ilość rdzeni a nie ich odsetek. Moja aplikacja nie umie
pracować na 1.34 rdzenia, umie pracować tylko na ich całkowitych ilościach. Dla mnie nie ma
problemu, mogę zadania oznaczyć jako 100 wątkowe. Ale nie wiem, czy wtedy klient z
czterema rdzeniami w ogóle pobierze takie zadanie.

Wracając do ułamkowych części rdzenia. Załóżmy że klient wpisał 1.34 rdzenia. Odczytuję
z ustawień i co mam zrobić? Mam utworzyć dwa wątki, czy jeden wątek? Czy może
pierwsze 34% zadania policzyć na 2 wątkach, a pozostałe 66% na jednym? A może
najpierw policzyć 66% na jednym, a na końcu 34% na dwóch? A może utworzyć dwa
wątki, na jednym system bez mojej ingerencji przydzieli 100%, a na drugim 34%?


Cytat: Karlik w 28 Lipiec 2013, 21:17
EDIT:
jak piszę o rdzeniach to mam na myśli samodzielną jednostkę obliczeniową, bo rdzenie w wypadku GPU to chyba nie jest najszczęśliwsze określenie  ;)
O GPU możemy zapomnieć przynajmniej przez najbliższe pół roku. Słyszałem że
NVIDIA wprowadziła ułatwienia do takich aplikacji jak perft, ale i tak nie mam czasu
na to :(


Pozdrawiam

Dario666

O tych ułamkowych częściach rdzenia to jakaś paranoja. Po pierwsze po co marnować czas na jakieś głupoty, jak praktycznie wszystkie projekty BOINC korzystają z całkowitej liczby rdzeni, więc na zadanie szachowe również pozostaje całkowita liczba rdzeni. Chyba, że  to są zadania GPU, ale wtedy i tak ten rdzeń jest "zajęty".

Żeby np. korzystać z 1,34 rdzenia to trzeba by kontrolować czas działania procesu i wstrzymywać go na określony okres. Zresztą jeśli "program szachowy" będzie działał na BOINCu to manager sam kontroluje czas działania aplikacji. Jak ustawimy na 2 rdzenie i 67% obciążenia to aplikacja sama będzia wykorzystywać 2x0,67 = 1,34 rdzenia.

krzyszp

Cytat: Dario666 w 29 Lipiec 2013, 09:31
Jak ustawimy na 2 rdzenie i 67% obciążenia to aplikacja sama będzia wykorzystywać 2x0,67 = 1,34 rdzenia.
Nie, aplikacja będzie wykorzystywać 2 rdzenie przez 67% czasu z godziny...

Fajne zegarki :)
Należę do drużyny BOINC@Poland
 Moja wizytówka

Karlik

Może niepotrzebnie wspominałem o tych ułamkowych, bo tylko zamieszanie wywołałem. Ułamkowe są głównie do zadań GPU, bo wtedy czasem część CPU się po prostu nudzi, dlatego mogą być uruchomione np. 3 takie zadania.

Co do ustawienia to dlatego pisałem o tym, żeby można to było kontrolować (przez dodanie jakiegoś ustawienia do profilu) i generowałbyś różne zadania: jak ktoś chce na jednym rdzeniu to mu podsyłasz takie zadanie, jak na dwóch to inne. Nie możesz ustawić na sztywno np. 8 wątków, bo wtedy klienci z mniejszą liczbą po prostu nie dostaną zadań (no dobra, można w BOINCu "emulować" większą liczbę - ale wtedy to mogłoby się mocno odbić na wydajności).

mariotti

Cytat: Karlik w 29 Lipiec 2013, 11:54
Może niepotrzebnie wspominałem o tych ułamkowych, bo tylko zamieszanie wywołałem. Ułamkowe są głównie do zadań GPU, bo wtedy czasem część CPU się po prostu nudzi, dlatego mogą być uruchomione np. 3 takie zadania.
Ależ bardzo dobrze że wspomniałeś, teraz mamy wyjaśnienie co to oznacza:
Cytat: krzyszp w 29 Lipiec 2013, 10:52
Cytat: Dario666 w 29 Lipiec 2013, 09:31Jak ustawimy na 2 rdzenie i 67% obciążenia to aplikacja sama będzia wykorzystywać 2x0,67 = 1,34 rdzenia.
Nie, aplikacja będzie wykorzystywać 2 rdzenie przez 67% czasu z godziny...

Cytat: Karlik w 29 Lipiec 2013, 11:54
Co do ustawienia to dlatego pisałem o tym, żeby można to było kontrolować (przez dodanie jakiegoś ustawienia do profilu) i generowałbyś różne zadania: jak ktoś chce na jednym rdzeniu to mu podsyłasz takie zadanie, jak na dwóch to inne. Nie możesz ustawić na sztywno np. 8 wątków, bo wtedy klienci z mniejszą liczbą po prostu nie dostaną zadań (no dobra, można w BOINCu "emulować" większą liczbę - ale wtedy to mogłoby się mocno odbić na wydajności).
Słabo widzę generowanie różnych zadań. Musiałbym wiedzieć ile prcent zadań przypadnie na
poszczególne ilości rdzeni. Jeśli będzie jeden użytkownik z super-komputerem (np. 500
rdzeni) to policzy więcej niż cała reszta razem wzięta. Jesli dam zadanie na 500 rdzeni i
nie znajdzie się ani jeden taki użytkownik, to zadanie nigdy się nie zakończy. Analogicznie
jest z pamięcią RAM. Jeśli będzie jeden wolontariusz z komputerem 500GB RAM i weźmie
dużą paczkę zadań, to będzie miał istotny wkład w obliczenia. Jednak jeśli w konfiguracji
dam takie wymagania pamięciowe, to ryzykuję że nie znajdzie się ani jeden taki
użytkownik.

Aplikacja jest napisana tak, żeby każde zadanie umiała policzyć na każdym komputerze.
Teoretycznie można tę aplikację skompilować na comodere64 i każde zadanie też powinna
prawidłowo policzyć - tyle że wolno. Więc nie mogę w zadaniach oznaczyć, że są one
tylko na 500 rdzeni, albo na 500GB RAM.

Trzeba jakoś inaczej rozwiązać ten problem, jeszcze nie wiem jak.

Pozdrawiam

Karlik

Nie wiem, może da się to jakoś dynamicznie ustawić (w sensie, że ten parametr dotyczący liczby wykorzystywanych rdzeni powiązać z aplikacją-klientem a nie z WorkUnitem). Tak czy siak raczej nie nastawiałbym się na użytkowników, którzy mają powyżej 12 rdzeni i ok. 16GB RAMu ;)

mariotti

#19
Cytat: Karlik w 29 Lipiec 2013, 13:52
Nie wiem, może da się to jakoś dynamicznie ustawić (w sensie, że ten parametr dotyczący liczby wykorzystywanych rdzeni powiązać z aplikacją-klientem a nie z WorkUnitem). Tak czy siak raczej nie nastawiałbym się na użytkowników, którzy mają powyżej 12 rdzeni i ok. 16GB RAMu ;)
Do wstępnych testów przyłączyła się osoba z komputerem 48-rdzeniowym. Ta jedna osoba
mogła policzyć więcej niż wszystkie inne osoby razem wzięte. Więc nie można zignorować takich
osób. Natomiast liczenie 48 tasków równolegle to w przypadku tej aplikacji strzał w stopę.

Pozdrawiam

Dario666

No tak, 2 x 67% czasu z godziny to średnio 134% prac godzinyy jednogo rdzenia.

Karlik

mariotti: no to masz kilka opcji:
1. spróbować znaleźć jakiś przełącznik, który pozwala na ustawienie parametrów zadania PO jego dodaniu do bazy (jak właśnie liczbę rdzeni)
2. zhackować własny program - zrobić sobie jakiś interfejs - jak już jest w pamięci jakaś instancja perfta to przed rozpoczęciem własnych obliczeń podpinasz się i pomagasz dokończyć obecny task
3. zmodyfikować scheduler (lub inny daemon), żeby dynamicznie ustawił liczbę rdzeni dla samego klienta (i pewnie jako parametr perfta) - w zależności od ustawień użytkownika (opcja jakbyś nie znalazł nic w punkcie pierwszym)
więcej nie przychodzi mi do głowy w tej chwili

Najbardziej elastyczny byłby chyba sposób drugi, ale to musisz sam ocenić. Ponieważ i tak masz wrapper to może wystarczyłoby sprawdzić czy istnieje jakaś obca instancja a potem wysłać jakiś sygnał (np. SIGUSR1, który oznaczałby "dodaj kolejny wątek, masz zielone światło" i SIGUSR2 "coś mnie wstrzymuje, zwolnij jeden wątek") - nie wiem jak by to wyglądało na windowsie niestety. No i wtedy trzeba pomyśleć co zrobić jak użytkownik da "wstrzymaj zadanie" na głównym wątku, ale wtedy chyba po prostu trzebaby zwolnić zasoby i wrapper drugiego mógłby spokojnie uruchomić swoją wersję.
No i dobrze by było, gdybyś umożliwił użytkownikowi ustawić maksymalną zajętość pamięci ;)

mariotti

Cytat: Karlik w 29 Lipiec 2013, 14:57
mariotti: no to masz kilka opcji:
1. spróbować znaleźć jakiś przełącznik, który pozwala na ustawienie parametrów zadania PO jego dodaniu do bazy (jak właśnie liczbę rdzeni)
Myślałem o czymś podobnym. Niestety takie rozwiązanie jest i pracochłonne i naraża cały
projekt na trudne do wychwycenia błędy :/

Cytat: Karlik w 29 Lipiec 2013, 14:57
2. zhackować własny program - zrobić sobie jakiś interfejs - jak już jest w pamięci jakaś instancja perfta to przed rozpoczęciem własnych obliczeń podpinasz się i pomagasz dokończyć obecny task
O tym też myślałem, mam podobne obawy jak powyżej.

Cytat: Karlik w 29 Lipiec 2013, 14:57
3. zmodyfikować scheduler (lub inny daemon), żeby dynamicznie ustawił liczbę rdzeni dla samego klienta (i pewnie jako parametr perfta) - w zależności od ustawień użytkownika (opcja jakbyś nie znalazł nic w punkcie pierwszym)
więcej nie przychodzi mi do głowy w tej chwili
Ja mam jeszcze kilka pomysłów, ale wszystkie wymagają roboty i zwiększają
ryzyko błędów :/

Cytat: Karlik w 29 Lipiec 2013, 14:57
Najbardziej elastyczny byłby chyba sposób drugi, ale to musisz sam ocenić. Ponieważ i tak masz wrapper to może wystarczyłoby sprawdzić czy istnieje jakaś obca instancja a potem wysłać jakiś sygnał (np. SIGUSR1, który oznaczałby "dodaj kolejny wątek, masz zielone światło" i SIGUSR2 "coś mnie wstrzymuje, zwolnij jeden wątek") - nie wiem jak by to wyglądało na windowsie niestety. No i wtedy trzeba pomyśleć co zrobić jak użytkownik da "wstrzymaj zadanie" na głównym wątku, ale wtedy chyba po prostu trzebaby zwolnić zasoby i wrapper drugiego mógłby spokojnie uruchomić swoją wersję.
No i dobrze by było, gdybyś umożliwił użytkownikowi ustawić maksymalną zajętość pamięci ;)

Koncepcyjnie proste, ale w realizacji będzie bardzo zagmatwane :/
Nadal nie wiem jak to prosto rozwiązać....

Mogę napisać aplikację GUI w QT. User ją pobierze ze strony projektu,
uruchomi i zobaczy dwa okienka:
1) MAX THREADS,
2) MAX RAM.
Aplikacja zapisze gdzieś dane i da pełne uprawnienia wszystkim do odczytu 0664.

Niestety nie wiem jak zachowa się aplikacja kliencka. Zadanie będzie dla 1 wątku, aplikacja
licząca uruchomi się w 8 wątkach i co wtedy? Aplikacja kliencka zgłosi błąd i zabije aplikację
liczącą? Nawet jakby się udało, to trzeba zablokować uruchamianie dwóch tasków
równolegle na tym samym kompie :/

Pozdrawiam

Karlik

Cytat: mariotti w 29 Lipiec 2013, 15:21
Mogę napisać aplikację GUI w QT. User ją pobierze ze strony projektu,
uruchomi i zobaczy dwa okienka:
1) MAX THREADS,
2) MAX RAM.
Aplikacja zapisze gdzieś dane i da pełne uprawnienia wszystkim do odczytu 0664.
No to od razu Ci powiem, że takie rozwiązanie jest chyba najgorsze z możliwych. Jak już to wyślij razem z aplikacją plik konfiguracyjny (jako input), ale żadnych graficznych konfiguratorów, które trzebaby uruchamiać i jeszcze zapisywałyby w dziwnych miejscach.
Cytat: mariotti w 29 Lipiec 2013, 15:21
Niestety nie wiem jak zachowa się aplikacja kliencka. Zadanie będzie dla 1 wątku, aplikacja
licząca uruchomi się w 8 wątkach i co wtedy? Aplikacja kliencka zgłosi błąd i zabije aplikację
liczącą? Nawet jakby się udało, to trzeba zablokować uruchamianie dwóch tasków
równolegle na tym samym kompie :/
Nie możesz modyfikować warunków po wysłaniu zadania, tzn. jak wyślesz WU na jeden wątek to NIE uruchamiasz żadnych dodatkowych wątków. NIGDY. Teoretycznie się da, ale to naprawdę w złym tonie i mogłoby zniechęcić do liczenia. Np. użytkownik chce Ci oddać jeden rdzeń, inne przeznaczając dla innych projektów albo zostawiając specjalnie wolne (z dowolnego względu). To teraz sobie wyobraź sytuację kiedy nagle zauważy, że zjadasz więcej rdzeni niż sobie życzy.
Ah, żeby nie było, chodzi mi o inną sytuację niż MAX_THREADS - tutaj ma np. 3, ale sytuacja jest taka: ma 4 rdzenie, na jednym liczy GPU, na drugim jakiś inny projekt, na pozostałych dwóch mógłby ewentualnie liczyć Twoje, Ty wyślesz mu zadanie typu "1 CPU" a w praktyce uruchomisz 3 wątki (bo niby tak ustawił) - po prostu ŹLE.
Musisz po prostu pamiętać o tym, że użytkownik może chcieć w kliencie ustawiać różne konfiguracje i musisz to uszanować.

krzyszp

Od takich rzeczy są często spotykane w projektach opcje konfigurowane bezpośrednio na stronie ustawień hosta (usera oczywiście), np. radioaktywny ma tam ustawienie czasu trwania próbki, ale generalnie możesz sobie ustawić co chcesz (o szczegóły pytaj TJM'a - on jest magik w temacie).
Ty możesz mieć tam konfiguracje rdzenie/wątki/ram dla aplikacji.

Co do samej wielowątkowości w projektach, to generalnie chyba nie jest to jeszcze dobrze dopracowane w BOINC i stąd zdarzajce się czasami kwiatki w niektórych projektach jak: taski nie dające się ubić, mnożące się ponad miarę, itd...
Przemyśl, czy jednak (przynajmniej na początek) nie pozostać przy jednym wątku i np. 4 lub 8GB Ram - zobacz, jaką wydajność oferuje społeczność w tej kategorii i przy okazji przez ten czas okaże się co i jak można poprawić/dodać/ująć...

Fajne zegarki :)
Należę do drużyny BOINC@Poland
 Moja wizytówka

mariotti

Hmmmm, a miała być taka elastyczna konfiguracja ;-)


Aplikacja już jest tak napisana, że wykorzystuje bardzo dobrze to, na co użytkownik jej
pozwoli. Im pozwoli na więcej, tym liczy szybciej. Na pewno nie będę jej pogarszał pod
żadnym pozorem ;) Może za pośrednictwem BOINC odpali się aplikację tak, jakby
użytkownik pozwolił tylko na jeden wątek. Piszę to z wielkim smutkiem, gdyż osoby z mocnymi
komputerami, a więc osoby najważniejsze dla projektu, nie będą mogły się wykazać, ani
pochwalić :(

Zrobię zaraz badanie, aby sprawdzić jaki jest wpływ pamięci na szybkość obliczeń.
Przypuszczam że jest to wpływ ogromny, więc odpalanie dwóch aplikacji równolegle,
bezwzględnie trzeba zablokować. Musi uruchamiać się jedna instancja i korzystać z
całej pamięci na jaką użytkownik się zgodził.

Dla perft byłoby idealnie, jakby użytkownik ustawił, że np. od godziny
2:00 do 6:00 wszystkie inne aplikacje BOINC są usypiane i zrzucane na swap, a
ze wszystkich zasobów (na które użytkownik się zgodził), korzysta tylko
perft. Po tym okresie perft jest usypiany i włącza się dopiero na drugi
dzień.

Pozdrawiam

AXm77

W ten sposób działa YAFU: procentowo dzieli czas na komputerze a nie zasoby.
W czasie kiedy robi obliczenia, YAFU jest jedynym aktywnym projektem
i zajmuje wszystkie dostępne (dla BOINC) rdzenie i całą pamięć.

http://yafu.dyndns.org/yafu/

mariotti

#27
Cytat: mariotti w 29 Lipiec 2013, 16:58
Zrobię zaraz badanie, aby sprawdzić jaki jest wpływ pamięci na szybkość obliczeń.
Coś zrobiłem, niestety na dwóch początkowych testach komputer miałem trochę
obciążony, więc duża ilość pamięci przyspiesza bardziej, niż widać to na zestawieniu.

3.00GB RAM time:2618s   
1.50GB RAM time:3149s
0.75GB RAM time:3686s
0.38GB RAM time:4175s
0.19GB RAM time:5024s
0.09GB RAM time:6188s
0.05GB RAM time:8604s
0.02GB RAM time:11006s

Więc jak ktoś odpali 32 osobne procesy, a tym samym podzieli dostępną pamięć na
te 32 procesy, to czas obliczeń jednego procesu wzrośnie około 2-3 razy.

Cytat: AXm77 w 29 Lipiec 2013, 20:51
W ten sposób działa YAFU: procentowo dzieli czas na komputerze a nie zasoby.
W czasie kiedy robi obliczenia, YAFU jest jedynym aktywnym projektem
i zajmuje wszystkie dostępne (dla BOINC) rdzenie i całą pamięć.
http://yafu.dyndns.org/yafu/
Użytkownik ściąga zadanie z projektu YAFU i w nim definiuje jak mają się
wykonywać zadania z innego projektu?

Pozdrawiam