Forum BOINC@Poland
Marzec 12, 2010, 02:27:53 *
Witamy, Gość. Zaloguj się lub zarejestruj.
Czy dotarł do Ciebie email aktywacyjny?

Zaloguj się podając nazwę użytkownika, hasło i długość sesji
Aktualności: Czy odwiedziłeś już wirtualne miasteczko BOINC@Poland?
 
   Strona główna   Portal Pomoc Szukaj Kalendarz Mapa użytkowników Tagi Zaloguj się Rejestracja  
Strony: 1 ... 36 37 38 39 [40] 41 42 43   Do dołu
  Dodaj zakładkę  |  Drukuj  
Autor Wątek: Tworzenie projektu... czyli powstanie i ewolucja Enigma@Home  (Przeczytany 60387 razy)
0 użytkowników i 1 Gość przegląda ten wątek.
TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #975 : Czerwiec 29, 2009, 18:26:49 »

Poprawiłem dziś dość poważny bug, który bezczelnie powodował, że niektóre zadania nigdy nie miały chęci się pobierać a w innych czasami znienacka wskakiwały validation errory. Wszystko przez konwersję z długich ciągów liczb na ciągi liczbowe i z powrotem, jedna z funkcji miała błąd przez co niektóre ciągi liczb były kodowane z błędem.

Zapisane



TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #976 : Lipiec 15, 2009, 22:56:12 »

Rozmawiałem z gościem, który testował na GPU algorytm podobny do tego, ktorego używa aplikacja Stefana Kraha - czyli jakąś odmianę hillclimba.
Rezultaty nie są zbyt zachęcające, zbyt wielu szczegółów nie udało mi się uzyskać bo koleś jest dość trudno osiągalny i nie dysponuje nadmiarem czasu, więc ciężko coś z niego wydobyć. W każdym razie z jego testów wynika, że algorytm wypada kiepsko na kartach graficznych, średniej klasy karty wypadają znacznie gorzej od CPU łykając przy tym dużo więcej prądu, co niejako je dyskwalifikuje.
Zastanawia mnie tylko czy i ewentualnie w jaki sposób puszczał jakieś równoległe wątki na karcie, czy też może po prostu odpalał jakąś jednowątkową wersję algorytmu, co by od razu wyjaśniało kiepską wydajność.

Normalnie workunit wygląda np tak:

B164:AA:AAAA~B164:AZ:ZZZZ

można to potraktować jako licznik, każda z literek od prawej do lewej będzie przeskakiwać kolejno od początku zakresu do końca przez wszystkie możliwe ustawienia: skrajne z prawej zawsze od A do Z, natomiast środkowe to ringi i zależnie od użytych rotorów jest 13 (A-N) lub 26 (A-Z) ustawień. Z lewej są rotory ustawione na sztywno, teoretycznie da się i rotory kolejno sprawdzać ale jest to bardziej skomplikowane i o wiele trudniej weryfikuje się poprawność wyników.
Podczas liczenia na CPU jednym wątkiem, dla każdego ustawienia wykonywane są pewne powtarzające się czynności:
wybierana jest kolejna pozycja startowa z zakresu, po czym program zaczyna od wygenerowania losowego steckera który potem jest losowo 'poprawiany', po każdej poprawce oblicza się 'score' dla rezultatu, jeśli jest lepszy zachowuje się zmianę, jeśli gorszy cofa i próbuje z innymi ustawieniami. Proces powtarzany jest kilkukrotnie, używając kolejno 3 metod obliczania score: ic-score (dane statystyczne), biscore i triscore (wartości oparte o słowniki zbitków 2 i 3 liter).
Najlepszy wynik jest zachowywany wraz z ustawieniami i jest to jedyna wartość jaką pamięta program, reszta jest odrzucana.

Stąd teoretycznie na GPU można od razu strzelić z grubej rury, podzielić otrzymany wraz z WU zakres na dowolną ilość mniejszych i pracować nad nimi równolegle, o ile przyniesie to jakiś wzrost wydajności. W takim wypadku koniecznie trzeba jedynie między wątkami jakoś dzielić aktualny najlepszy wynik, no i pilnować, żeby ewentualny dobry wynik nie został jakoś nadpisany gorszym o ile np. dwa wątki w tym samym momecie stwierdzą, że poprzedni jest gorszy od tego co znalazły. Nie wiem jak wygląda synchronizacja danych między wątkami na GPU, na CPU nie jest to zbyt trudne i z łatwością można by napisać multi-threaded enigmę, ale jest bo bez sensu bo wygodniej po prostu odpalić kilka procesów.
Zastanawia mnie też, czy taki numer (tzn odpalenie kilku niezależnych progsów) przejdzie również w przypadku GPU ? Podziału WU można dokonać w dowolnym momencie, serwer zamiast jednego długiego może wysłać 10 krótkich do odpalenia równolegle na grafie, rezultat będzie taki sam - jeden wynik będzie najlepszy, 9 będzie gorsze, tylko normalna aplikacja sama odrzuciłaby 9 i oddała 1 do serwera.
Zapisane



sesef
Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 857


Moja ulubiona ocena: 2 + j5


Zobacz profil WWW Nagrody
« Odpowiedz #977 : Lipiec 15, 2009, 23:44:19 »

Zastanawia mnie też, czy taki numer (tzn odpalenie kilku niezależnych progsów) przejdzie również w przypadku GPU ? Podziału WU można dokonać w dowolnym momencie, serwer zamiast jednego długiego może wysłać 10 krótkich do odpalenia równolegle na grafie, rezultat będzie taki sam - jeden wynik będzie najlepszy, 9 będzie gorsze, tylko normalna aplikacja sama odrzuciłaby 9 i oddała 1 do serwera.

Takie rozwiązanie byłby najprostsze, ale wtedy następuje 1 problem mianowicie checkpointy, chyba że jesteś w stanie wygenerować wu, które da się podzielić na ~5k mniejszych i na tyle długich żeby np taki pentium III 800-1000 mhz liczył takie jedno małe WU koło minuty.

BTW. Większych zakresów liczbowych niż 32 bit w enigmie nie ma?
Zapisane

TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #978 : Lipiec 16, 2009, 00:13:41 »

WU są dowolnie skalowalne, najlepszy wynik zawsze jest tylko jeden i reszta to teoretycznie śmieci. Z tym że dla każdego wysłanego rezultatu serwer trzyma zwrócony wynik, więc dzieląc po stronie serwera WU otrzymuję więcej wyników. Za bardzo nie można szaleć, bo nawet z normalnymi WU bazy wychodzą ogromne.
Można by jednak na potrzeby GPU stworzyć dwustopniową aplikację, która otrzymuje normalny, długi WU od serwera i sama dzieli go na kilka mniejszych, odpala właściwe aplikacje przeliczające i zwraca najlepszy wynik do serwera.

Najmniejszy możliwy workunit to coś typu B164:AA:AAAA~B164:AA:AAAB i jest to praktycznie niezmierzalny czas przeliczania (ułamki sekundy dla byle proca). Można go dowolnie wydłużać np. B164:AA:AAAA~B164:AA:AAZZ jest już 26*26 dłuższy.

Jedyną dużą liczbą w całym programie jest score, bi- i triscore zależą użytych słowników i długości tekstu, zazwyczaj mieszczą się jednak w zwykłym INT, dla słownika '1941' nawet spokojnie w unsigned mediumint dla bardzo długich tekstów (według typów danych MySQLa), bo po prostu mniejsze liczby są przypisane do ciągów znaków w tym słowniku.
ic-score chyba nie mieści się w zwykłym INT, stąd na końcu funkcji jest dzielenie żeby się zmieścić w sensownym zakresie, jednak czy zamiana tej jednej liczby na 64 bitową i rezygnacja z dzielenia coś zmieni nie sprawdzałem.
Zapisane



TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #979 : Lipiec 18, 2009, 20:56:35 »

Trzeba jakoś specjalnie definiować liczbę jako 64 bitową ?
Po samym usunięciu dzielenia program niestety sypie się w niektórych przypadkach (np. benchmarkowy testcase), więc prawie na pewno następuje przepełnienie zwykłego INTa.
Jednak moje doświadczenie z 64 bitami jest delikatnie mówiąc nienajlepsze (żeby nie powiedzieć żadne :ouch:), stąd nie wiem co zrobić, żeby to działało i przy tym zgodne było z jakimiś standardami.
Dzielenie jest dość czasochłonne, więc jest szansa że usunięcie go z funkcji która jest jedną z głównych w programie powinno coś pomóc. Prawie na pewno program przyspieszy o kilka-kilkanaście procent, przyspieszenie to widać nawet zastępując oryginalną funkcję ic-score inną, bardziej skomplikowaną ale jednocześnie bez końcowego dzielenia (niestety generującą przy tym niekompatybilne wyniki, więc nie można ich używać zamiennie).

Zapisane



sesef
Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 857


Moja ulubiona ocena: 2 + j5


Zobacz profil WWW Nagrody
« Odpowiedz #980 : Lipiec 18, 2009, 21:23:10 »

Trzeba jakoś specjalnie definiować liczbę jako 64 bitową ?
Po samym usunięciu dzielenia program niestety sypie się w niektórych przypadkach (np. benchmarkowy testcase), więc prawie na pewno następuje przepełnienie zwykłego INTa.
Jednak moje doświadczenie z 64 bitami jest delikatnie mówiąc nienajlepsze (żeby nie powiedzieć żadne :ouch:), stąd nie wiem co zrobić, żeby to działało i przy tym zgodne było z jakimiś standardami.
Dzielenie jest dość czasochłonne, więc jest szansa że usunięcie go z funkcji która jest jedną z głównych w programie powinno coś pomóc. Prawie na pewno program przyspieszy o kilka-kilkanaście procent, przyspieszenie to widać nawet zastępując oryginalną funkcję ic-score inną, bardziej skomplikowaną ale jednocześnie bez końcowego dzielenia (niestety generującą przy tym niekompatybilne wyniki, więc nie można ich używać zamiennie).

A co chcesz zrobić? może masz problem typu że mnożysz jakąś liczbą, która jest typu 32bit przez stałą co w wyniku da już liczbę 64bit. Kompilator nie jest w stanie tego sprawdzić więc przyjmuje że wynik takiego mnożenia będzie 32bit nawet jak wynik takiego działania przypisujesz do typu 64 bit;

Przykład:

int64_t x; //64 bitowa liczba wynikowa
int32_t y; //32 bitowy liczba

x = y * 2147483647LL; //zamiast dopisywać LL do stałej można rzutować y na int64_t x = (int64_t)y * 2147483647;

wynikiem takiego działania jeżeli y != 0 na pewno będzie liczba 64 bit jednak jakbyśmy zapisali to tak x = y * 2147483647; to wynik będzie 32 bitowy pomimo tego że x został zadeklarowany jako 64bit. Niektóre kompilatory (może wszystkie) tak maja, że jak mu nie pokażesz, że chcesz 64 bit to tego nie zrobi
Zapisane

TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #981 : Lipiec 18, 2009, 23:31:43 »

W progsie jest pętla w której wynik powstaje przez kilka(naście) -> n kolejnych mnożeń, a że powstająca liczba jest okrutnie wielka, zastosowane jest tam też dzielenie (przez n właśnie), dzięki czemu mieści się w rozsądnym zakresie.
Dążę do tego, żeby ta liczba mogła być okrutnie wielka (czyli w praktyce 64 bitowy INT), wtedy obejdzie się bez dzielenia, czyli powinno to zaoszczędzić trochę czasu procesora.
Teraz jednak pojawia się pytanie: czy dla 64 bitowego procesora, aplikacji i systemu działania na 64 bitach będą równie szybkie jak na 32 ? W aplikacji ewentualnie powstający 64 bitowy wynik będzie ciągle porównywany z innymi (najlepszy jest przechowywany), więc jeśli okaże się, że porównanie dwóch 64 bitowych liczb jest wolniejsze niż dla 32 bitowych, to przyrost prędkości aplikacji może okazać się ujemny...
Jeszcze muszę luknąć jak to wygląda w oryginalnych źródłach obecnejaplikacji, bo to w czym obecnie dłubię to stara i dużo wolniejsza wersja, ale przez to lepsza do testów, bo wszelkie zmiany są bardziej widoczne.
Zapisane



sesef
Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 857


Moja ulubiona ocena: 2 + j5


Zobacz profil WWW Nagrody
« Odpowiedz #982 : Lipiec 18, 2009, 23:52:45 »

W progsie jest pętla w której wynik powstaje przez kilka(naście) -> n kolejnych mnożeń, a że powstająca liczba jest okrutnie wielka, zastosowane jest tam też dzielenie (przez n właśnie), dzięki czemu mieści się w rozsądnym zakresie.
Dążę do tego, żeby ta liczba mogła być okrutnie wielka (czyli w praktyce 64 bitowy INT), wtedy obejdzie się bez dzielenia, czyli powinno to zaoszczędzić trochę czasu procesora.
Teraz jednak pojawia się pytanie: czy dla 64 bitowego procesora, aplikacji i systemu działania na 64 bitach będą równie szybkie jak na 32 ? W aplikacji ewentualnie powstający 64 bitowy wynik będzie ciągle porównywany z innymi (najlepszy jest przechowywany), więc jeśli okaże się, że porównanie dwóch 64 bitowych liczb jest wolniejsze niż dla 32 bitowych, to przyrost prędkości aplikacji może okazać się ujemny...
Jeszcze muszę luknąć jak to wygląda w oryginalnych źródłach obecnejaplikacji, bo to w czym obecnie dłubię to stara i dużo wolniejsza wersja, ale przez to lepsza do testów, bo wszelkie zmiany są bardziej widoczne.

Porównanie liczb 64 bit na procesorze x64 to praktycznie to samo co porównanie liczb 32 bit na procku 32 bit. Po to powstało rozszerzenie x86_x864 żeby operacje na dużych liczbach 64 bit robić jedną instrukcją, a nie jak to ma miejsce na 32 bitowym procku przy pomocy kilku instrukcji. Zmień deklaracje zmiennej wynikowej na unsigned long long (deklaracja standardowa dla linuxa i windowsa) a przy wszystkich składnikach z których powstaje ten wynik dodaj dodatkowo przed zmienna rzutowanie na 64 bit (unsigned long long) i powinno działać. Pozbycie się dzielenia na x64 powinno przyspieszyć liczenie, na systemie x86 nie koniecznie, teoretycznie powinno być nawet wolniej z dzieleniem.
Zapisane

TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #983 : Lipiec 27, 2009, 01:39:11 »

Dłubałem dziś sporo przy aplikacji, testowałem wydajność głównie pod linuksem ze względu na dostęp do 4 kompilatorów - 2 wersje gcc, Intel i Open64.
Wyżej wspomniane kombinowanie z 64 bitami ma sens raczej tylko jako dodatek do innych optymalizacji. Samodzielny przyrost prędkości jest raczej mizerny, na dodatek 64 bitowe kompilacje na procesorach Intela są po prostu wolniejsze od starych aplikacji zbudowanych przy użyciu gcc 3.2, tak więc nawet z przyspieszeniem po usunięciu paru drobiazgów przyrost prędkości przy przesiadce 32->64bit jest ujemny.

Nie rozumiem jednak wielu rzeczy. Na przykład tego:

Kod:
  s0 = s1 = s2 = s3 = 0;
  for (i = 0; i < len-15; i += 16) {
    c1 = stbrett[ciphertext[i]];
    c1 = path_lookup[i][c1];
    c1 = stbrett[c1];
    s0 += unidict[c1];

    c2 = stbrett[ciphertext[i+1]];
    c2 = path_lookup[i+1][c2];
    c2 = stbrett[c2];
    s1 += unidict[c2];
[.....]
[.....]
[.....]
    c3 = stbrett[ciphertext[i+2]];
    c3 = path_lookup[i+2][c3];
    c3 = stbrett[c3];
    s2 += unidict[c3];

    c4 = stbrett[ciphertext[i+3]];
    c4 = path_lookup[i+3][c4];
    c4 = stbrett[c4];
    s3 += unidict[c4];
  }
  for (; i < len; i++) {
    c1 = stbrett[ciphertext[i]];
    c1 = path_lookup[i][c1];
    c1 = stbrett[c1];
    s0 += unidict[c1];
  }

  return (s0+s1) + (s2+s3);

Score które jest zwykłą sumą liczone jest na 4 zmiennych i na sam koniec po prostu sumowane. Oczywiście można wywalić te 4 zmienne i zostawić jedną, odpada też wtedy suma na końcu, ale pojawiają się ciekawe efekty:

-na procesorach typu PIII i pochodnych ogromny spadek wydajności
-na Athlonach 64/64 x2 lekki przyrost wydajności (rzędu 2%)
-na architekturze c2d nie widać zmian

Na dodatek dużo zależy tu od kompilatora, z tego co pamiętam właśnie z tym oryginalnym kodem na 4 zmiennych aplikacja skompilowana kompilatorem Intela na linuksie po prostu zmiata wydajnością wszystkie inne, wydajność jest tak ogromna, że gdyby istniały 4GHz PIII byłyby to najprawdopodobniej najlepsze procesory w projekcie - wydajność z każdego MHz lepsza jest chyba tylko na najmocniejszych C2D.

Z tego co czytałem w podręczniku kompilatora Intela, dość możliwe jest, że takie rozbite niezależne działania procesor jest w stanie wykonywać jednocześnie. Ale nie tłumaczy to, dlaczego w takim razie aplikacja zbudowana pod C2D, PIV czy inne nowsze procesory działa tak samo szybko, niezależnie od tego czy operuje na jednej zmiennej czy na czterech. Próbowałem nawet na 8 i 16 ale zmian nie widać.

Kolejna sprawa to tajemnicze -fschedule-insns na procesorach AMD.
Na procesorach Intela najwyższą wydajność uzyskuje się przez ręczne rozwinięcie kodu, tzn wszystkie wywołania drobniejszych funkcji zastępuję po prostu tą funkcją wklejoną w miejsce wywołania. Kod źródłowy jest po takiej akcji kobylasty, a plik wykonywalny wielki jak drzwi od stodoły, ale przyspieszenie na procesorach klasy c2d rzędu 10-15% więc nie do pogardzenia. Tak działa obecnie używana aplikacja dla c2d.
Na procesorach AMD jednak taki numer nie przechodzi, bo gcc wywala błędy przy próbie kompilacji tak rozwiniętego kodu z flagą -fschedule-insns, która jak zostało udowodnione jest kluczowa dla wydajności na prockach AMD. Bez tej flagi kod się kompiluje, ale zysk prędkości biorący się z braku wywołań funkcji zatraca się poprzez stratę wydajności przy braku -fschedule-insns. Z Open64 i rozwiniętym kodem również były jakieś zgrzyty kompilacji.

Jedno jeszcze mnie dziwi - na forum projektu mdoerner zarzucił kompilacje z Open64 m.in. właśnie dla Athlona 64 i 64x2 - te jego exeki chodzą w miarę przyzwoicie, śmiem nawet przypuszczać, że są to obecnie najszybsze dla tych Athlonów pod 32 bitowe systemy.
Jednak dziś próbowałem wykrzesać coś więcej z tego kompilatora i choćbym na rzęsach chodził po suficie nie mogłem uzyskać nawet zbliżonego wyniku; co więcej nie mogłem nawet uzyskać wyniku zbliżonego do byle chłamowatej kompilacji z gcc... Średnia kiepskich gcc-buildów w benchmarku którego dziś używałem (krótki, żeby nie zasnąć oczekując) to 24s, podobną wydajność osiągał exek skomplilowany Intelem z flagami generic x86 tak żeby progs działał również na AMD. Najszybszy exek z Open64 jaki udało mi się wykrzesać osiągnął 28s i co ciekawe, obojętnie jakie opcje bym do kompilacji nie dodawał czas ten znacznie się nie zmienia - są praktycznie tylko dwa stany: 1) progs się kompiluje i osiąga te 28s 2) wyskakuje błąd informujący o złych opcjach albo błąd kompilacji po włączeniu jakiejś opcji. WTF ?

Wygląda na to, że w źródłach czai się jeszcze spora rezerwa prędkości do wyciśnięcia, tylko trzeba porzucić jedno, wspólne źródło i spróbować z co najmniej dwoma róznymi wersjami: Intel/AMD lub co gorsza jeszcze jakieś wersje pośrednie, bo podejrzewam, że między Athlonami a Phenomem też różnice będą spore...
Zapisane



buninek
Młodszy Liczydłowy
*
Offline Offline

Wiadomości: 410


Zobacz profil Nagrody
« Odpowiedz #984 : Lipiec 27, 2009, 18:53:07 »

Duży mankament, to niemożność rozsyłania optymalek do konkretnych CPU bezpośrednio przez serwer.

W tym projekcie brakuje tylko jeszcze jednej dobrej optymalki. Dla procesorów amd liczących pod windowsem.

Kiedyś przeglądałem statystyki hostów i jest tam całe stado amd x2 6000. Akurat liczyłem na swoim x2@2700 i
średnio miałem prawie 70% lepsze czasy. Różnica znaczna.

Zbudowanie może być trudne. Pewnie byłaby szybka, jeśliby udałoby się użyć  mingw (64-bit) z -fschedule-insns
(małe szanse). Wtedy mógłbyś na siłę je wcisnąć z serwera na te kompy. Cheesy

Build mdoernera, kompilowany open64 testowałem. W moim przypadku wolniejszy o kilka %.
Choć ta aplikacja w przypadku procesorów phenom i nowszych procków ze stajni amd może wyppadać lepiej.

Jeśli masz ochotę możesz jeszcze testnąć moją aplikację (gcc-3.4.6) dla amd. Działa pod 64-bitowym systemem.
http://files.getdropbox.com/u/349831/enigma.static.x86_64.tar.bz2
« Ostatnia zmiana: Lipiec 27, 2009, 19:08:59 wysłane przez buninek » Zapisane
TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #985 : Lipiec 28, 2009, 01:04:34 »

Oprócz tego, że 'brakuje' aplikacji Windows/AMD, wszystkie inne da się przyspieszyć modyfikując źródła pod konkretny procesor i używając właściwych flag. Niestety, kombinacji jest łącznie tyle, że po paru godzinach zabawy już się nie pamięta co z czym i jak łączyć. Trzeba by jakoś usystematyzować wiedzę i wprowadzać kolejne zmiany w źródłach, sprawdzać na każdym procku jakie są efekty i kompilować z różnymi flagami.
Aplikacji 64 bitowej pod AMD chwilowo nie przetestuję, bo nie mam pod ręką kompa z Athlonem i 64bitowym systemem.
Zapisane



[GPU Force] Robert 7NBI
Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 831


Wybieram wolność. Zawsze.


Zobacz profil WWW Nagrody
« Odpowiedz #986 : Lipiec 31, 2009, 00:18:16 »

Tak a`propos - mam AMD Phenom x4 9650 + Win7/64 i chętnie coś potestuję. A na tę chwilę mam krótkie pytanie - który z exe z poniższego linku użyć do mojego procka?
http://www.enigmaathome.net/forum_thread.php?id=17&nowrap=true#1166
Zapisane

TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #987 : Lipiec 31, 2009, 01:28:22 »

Nie wiem, wypadałoby zrobić benchmark i po prostu wybrać najszybszy. Gdzieś na poprzednich stronach tego wątku jest opis jak wykonywać pomiary. Sprowadza się to do uruchomienia exeka z odpowiednimi parametrami i sprawdzenia ile czasu procesora użył do momentu zakończenia pracy.
Zapisane



TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #988 : Sierpień 13, 2009, 14:10:06 »

Wygląda na to, że pojawiły się jakieś nowe optymalizacje które nie są publicznie dostępne. Przypominają to co kiedyś sam skleciłem - aplikacja działa super szybko, ale niektórych zadań nie jest w stanie przetworzyć.
Przez to ładne parędziesiąt godzin przesiedziałem ostatnio poprawiając logikę assimilatora i validatora. Wcześniej zadania zweryfikowane jako błędne przetwarzane były przez główny serwer (to co siedzi 'nad' BOINCem, jako łączność z serwerem M4). Niestety rosnąca liczba nieprawidłowych rezultatów zaczęła mi zakłócać działanie tego systemu, do tego stopnia, że w tabelach aktywnych zadań chwilami wisiało po 500-600 tysięcy workunitów, które w BOINCu po kilka razy z rzętu trafiały na hosty nie będące w stanie ich przetworzyć. Są nawet hosty z aplikacjami które w ogóle nic nie są w stanie przeliczyć (nie wiem jak to w ogóle możliwe), a mimo to są podpięte i codzień kaszanią swoją dzienną dawkę zadań.

W związku z tym wprowadziłem duże zmiany - dla użytkowników ze sprawnie działającymi aplikacjami zmian praktycznie nie ma, oprócz tego, że nie można sobie resetować daily quota.
Wcześniej serwer 'wybaczał' drobne błędy i wysypanie się workunita raz na jakiś czas po prostu ignorował, nie obniżając daily quota. To dlatego, że błędne próbki w żaden sposób nie są w stanie wpłynąć na działanie całości, a wiadomo, że zdarzają się z różnych powodów - nadmierne O/C, jakiś zwisek systemu czy coś.
Teraz jest to zrobione na trochę innej zasadzie - dla hostów które przez dłuższy czas zwracały poprawne rezultaty, dalej stosowana jest polityka 'przymykania oka' na pojedyńcze błędy. Za to dla hostów, które regularnie zwracają dużą liczbę błędnych zadań limity są zaostrzone - daily quota leci lawinowo w dół, aż do momentu kiedy zwrócenie nawet jednego zadania z błędem automatycznie odcina hosta na następne 24h (daily quota od razu wskakuje na 1). Po kilku dniach działania nowego systemu kilka hostów już się na to załapało (nikt z naszego teamu).
Zapisane



[GPU Force] Robert 7NBI
Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 831


Wybieram wolność. Zawsze.


Zobacz profil WWW Nagrody
« Odpowiedz #989 : Sierpień 13, 2009, 14:28:18 »

To ciekawa informacja. A jak do tego mają się zadania przerwane przez użytkownika? Jestem "karany" za coś takiego, czy jest to neutralne? Chodzi mi o ogólną zasadę, nie tylko o ustawy Enigmy.

Jestem tu nowy i wciąż eksperymentuję z różnymi projektami. Czasem, żeby dostać jakąś próbkę muszę ustawić zapas na kilka dni. Niestety "przy okazji" z takiego np. PG zdąży wpaść i 50 wu, które później wywalam. Wiem, że należy nastawić "nie pobieraj", ale czasem zdarza się zapomnieć.
Zapisane

AiDec
_
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 1 949


Punkciki-punkciki man :)


Zobacz profil Nagrody
« Odpowiedz #990 : Sierpień 13, 2009, 14:43:21 »

Standardowo, w prawie wszystkich projektach, przerwanie zadania jest rownoznaczne z niepoprawnym przeliczeniem. A zatem obniza daily quota.
Zapisane

TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #991 : Sierpień 13, 2009, 14:57:16 »

Dokładnie tak to działa, na dodatek w starszych wersjach serwera przerwanie podbijało error_rate hosta, czy nadal tak jest nie sprawdzałem. To drugie jest totalnie bez sensu, bo anulowanie zadań jest na pewno lepszym sposobem niż ich kiszenie aż przekisną w wypadku nadmiaru - z anulowanym zadaniem serwer radzi sobie doskonale wysyłając od razu resenda, kiszone wisi w bazie aż do timeouta, po czym również następuje resend, ale workunit jako taki ma wpisy w bazie ze 2 razy dłużej.
Tutaj jednak sytuacja jest jeszcze trochę inna, podczas procesu walidacji serwer może początkowo obniżyć daily quota za anulowanie zadań (pozostałość BOINCowego kodu validatora), ale i tak przywróci maksymalną wartość przy pierwszym poprawnym zwróconym wyniku, bo daemon który zajmuje się ustalaniem aktualnej wartości nresults_today i daily_quota ma po prostu w nosie takie drobiazgi, jak anulowanie zadań. Dla niego liczą się tylko poprawność/niepoprawność wyniku.

Rozważam jeszcze możliwość wprowadzenia bonusu dla 'reliable hostów' - komputery które w momencie odsyłania wyniku miałyby error_rate = 0, mogłyby dostawać jakiś dodatek do punktów za zadanie. Takie komputery są szczególnie cenne z punktu widzenia każdego projektu, bo trafiają do nich zadania które często nie będą miały więcej szans na przeliczenie. Przykładowo, w enigmie zadanie ma około 28 dni na powrót do serwera M4, to daje możliwość przekiszenia zadania dwa razy, ale trzeci resend zostanie wysłany ze skróconym deadline i jeśli nie wróci w czasie, serwer M4 takiego rezultatu nie przyjmie. Co prawda serwer nadal potrafi obsłużyć taki rezultat (czeka na inny workunit z serwera M4 z tymi samymi danymi, do których rezultat będzie pasował), jednak kosztem bardzo obciążających operacji na bazie danych.
« Ostatnia zmiana: Sierpień 13, 2009, 15:04:34 wysłane przez TJM » Zapisane



TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #992 : Sierpień 16, 2009, 15:13:39 »

Poprawiłem dziś resztę drobnych bugów w backendzie i przy okazji znalazłem bug w BOINCu lub przynajmniej jego dokumentacji.
Domyślnie pole workunit.name to max 254 znaki tekstu. Założony jest indeks który automatycznie zabrania wstawienia dwóch workunitów o takiej samej nazwie.
Ale kto by przypuszczał, że nikt nie pomyślał wstawić tam do typu danych BINARY ? Bez tego dupa = dUPa = DUPA, więc nie da się wstawiać również workunitów o nazwach innych, pisanych z różną wielkością liter. Przez to serwer po prostu nie chciał mi wstawiać niektórych workunitów do tabeli, a ja się głowiłem czemu...

« Ostatnia zmiana: Sierpień 16, 2009, 16:03:00 wysłane przez TJM » Zapisane



TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #993 : Sierpień 16, 2009, 18:48:23 »

Zbudowałem z ciekawości nowy set optymalizowanych aplikacji, w VS 2008. Są tylko dwie sensowne: SSE i SSE2.
Na razie szału nie ma, uzyskałem wyniki na poziomie zbliżonym do starych najlepszych aplikacji. Ale myślę, że zmieniając w opcjach co nieco da się jeszcze dorzucić jakiś bonus do prędkości, więc niewykluczone, że dałoby radę zbudować coś szybszego. Niestety nie używam VS na codzień, więc nie bardzo wiem od czego zacząć.
Orientuje się ktoś, czy jeśli ustawię inline functions -> any suitable, to nadal kompilator będzie brał pod uwagę funkcje oznaczone jako _inline_ ? GCC miał z tym poważne problemy, musiałem całe źródło przepisać, tak żeby w ogóle nie było tych funkcji.

EDIT: oraz fajnie by było, gdyby ktoś z AMD/Win32 przetestował jak się miewa prędkość, może dla AMD będzie na dzieńdobry lepiej niż standard z MinGW.
Zapisane



sesef
Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 857


Moja ulubiona ocena: 2 + j5


Zobacz profil WWW Nagrody
« Odpowiedz #994 : Sierpień 16, 2009, 20:26:59 »

Zbudowałem z ciekawości nowy set optymalizowanych aplikacji, w VS 2008. Są tylko dwie sensowne: SSE i SSE2.
Na razie szału nie ma, uzyskałem wyniki na poziomie zbliżonym do starych najlepszych aplikacji. Ale myślę, że zmieniając w opcjach co nieco da się jeszcze dorzucić jakiś bonus do prędkości, więc niewykluczone, że dałoby radę zbudować coś szybszego. Niestety nie używam VS na codzień, więc nie bardzo wiem od czego zacząć.
Orientuje się ktoś, czy jeśli ustawię inline functions -> any suitable, to nadal kompilator będzie brał pod uwagę funkcje oznaczone jako _inline_ ? GCC miał z tym poważne problemy, musiałem całe źródło przepisać, tak żeby w ogóle nie było tych funkcji.

EDIT: oraz fajnie by było, gdyby ktoś z AMD/Win32 przetestował jak się miewa prędkość, może dla AMD będzie na dzieńdobry lepiej niż standard z MinGW.

Kompilator z VS2008 nie jest zły, ale jak już przebudowałeś source tak, żeby działało pod VS2008 (kiedyś próbowałem, no ale jakieś linuxowe funkcje tam siedziały, więc dałem sobie spokój ) to zainteresuj się kompilatorem intela dla windowsa powinno dać dużo lepsze przyspieszenie niż sam vs.

Możesz podesłać przerobione source to może i ja bym się trochę pobawił?
Zapisane

TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #995 : Sierpień 16, 2009, 22:26:58 »

Nie potrafię w ogóle podpiąć kompilatora Intela pod Visual Studio, kiedyś ostro z tym walczyłem ale miałem poważne problemy. Udało mi się jedynie pod Visual C++.
Źródło później gdzieś wrzucę, mam chwilowo jedynie jakieś niechlujne na którym dużo rzeczy testowałem, ale projekt i patch da się spokojnie nałożyć na domyślne.

Nie wiesz jak wygląda sytuacja z inline funkcjami w visualu ? Domyślnie nie wciąga nawet najprostszych funkcji jako inline (widzę to od razu po wielkości exeka), a z doświadczenia wiem, że daje to spory przyrost prędkości. Z kolei gdy zdeklaruję coś z inline, __inline lub __forceinline, kompilacja sypie się z błędami linkera.
Zapisane



sesef
Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 857


Moja ulubiona ocena: 2 + j5


Zobacz profil WWW Nagrody
« Odpowiedz #996 : Sierpień 16, 2009, 22:31:35 »

Nie wiesz jak wygląda sytuacja z inline funkcjami w visualu ? Domyślnie nie wciąga nawet najprostszych funkcji jako inline (widzę to od razu po wielkości exeka), a z doświadczenia wiem, że daje to spory przyrost prędkości. Z kolei gdy zdeklaruję coś z inline, __inline lub __forceinline, kompilacja sypie się z błędami linkera.

inline jakoś nie chce działać na VS ten sam problem był podczas kompilacji milky nie chciał dodawać inline takich funkcji jak sin czy cos a z tego co potem mindc wykombinował na intelu to już wszystko ładnie poszło.

Nie potrafię w ogóle podpiąć kompilatora Intela pod Visual Studio, kiedyś ostro z tym walczyłem ale miałem poważne problemy. Udało mi się jedynie pod Visual C++.
Źródło później gdzieś wrzucę, mam chwilowo jedynie jakieś niechlujne na którym dużo rzeczy testowałem, ale projekt i patch da się spokojnie nałożyć na domyślne.

Korzystasz z darmowej wersji express? Kiedyś potrzebowałem na szybko kompilator x64 a na maszynie była tylko wersja express i niestety nie udało mi się zmusić kompilatora do działania. Na domowej maszynie mam wersje Team System i nie ma takich problemów.
Zapisane

TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #997 : Sierpień 16, 2009, 22:47:01 »

No cóż, widocznie będę musiał ręcznie rozwinać źródło, jak dla gcc który też coś sapał. Wtedy niedziałanie inline samego kompilatora nie jest problemem.

Co do VS, to mam full wersję, ale mimo to miałem jakieś problemy. Niestety wyczerpałem 30-day triala na obu zainstalowanych systemach, więc póki co nawet nie potestuję czy da się coś jeszcze z tym zrobić.
Zapisane



sesef
Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 857


Moja ulubiona ocena: 2 + j5


Zobacz profil WWW Nagrody
« Odpowiedz #998 : Sierpień 16, 2009, 22:54:19 »

Co do VS, to mam full wersję, ale mimo to miałem jakieś problemy. Niestety wyczerpałem 30-day triala na obu zainstalowanych systemach, więc póki co nawet nie potestuję czy da się coś jeszcze z tym zrobić.

Do testów możesz zainstalować wersje express ten sam kompilator tylko nie ma x64 jest jedynie x86 i trochę okrojony interfejs, ale z tego co pamiętam opcje kompilacji wszystkie te same.

Edit

Ahh te 30 dni to chodziło o intela, a nie o VS, co do samego intela tez ciekawa sprawa bo zainstalowałem u siebie triala ze strony intela i jakos na win7 ten trial się nie kończy Cheesy
Zapisane

TJM
Grupa Reagowania Operacyjno-Manewrowego
Starszy Liczydłowy
*
Offline Offline

Płeć: Mężczyzna
Wiadomości: 2 142


Smokin` 5 clients to nachapać more


Zobacz profil WWW Nagrody
« Odpowiedz #999 : Sierpień 17, 2009, 00:32:54 »

U mnie trial przywiesił się na ostatnich dniach, ale ostatecznie w końcu kompilator i tak się przyblokował.

Nie rozumiem jednej rzeczy kurcze.


Kod:
double icscore(const int *stbrett, const int *ciphertext, int len)
{
  int f[26] = {0};
  int S0, S1, S2, S3;
  int c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16;
  int i;

  if (len < 2)
    return 0;

  for (i = 0; i < len-15; i += 16) {
    c1 = stbrett[ciphertext[i]];
    c1 = path_lookup[i][c1];
    c1 = stbrett[c1];

    c2 = stbrett[ciphertext[i+1]];
    c2 = path_lookup[i+1][c2];
    c2 = stbrett[c2];

    c3 = stbrett[ciphertext[i+2]];
    c3 = path_lookup[i+2][c3];
    c3 = stbrett[c3];

    c4 = stbrett[ciphertext[i+3]];
    c4 = path_lookup[i+3][c4];
    c4 = stbrett[c4];

    c5 = stbrett[ciphertext[i+4]];
    c5 = path_lookup[i+4][c5];
    c5 = stbrett[c5];

    c6 = stbrett[ciphertext[i+5]];
    c6 = path_lookup[i+5][c6];
    c6 = stbrett[c6];

    c7 = stbrett[ciphertext[i+6]];
    c7 = path_lookup[i+6][c7];
    c7 = stbrett[c7];

    c8 = stbrett[ciphertext[i+7]];
    c8 = path_lookup[i+7][c8];
    c8 = stbrett[c8];

    c9 = stbrett[ciphertext[i+8]];
    c9 = path_lookup[i+8][c9];
    c9 = stbrett[c9];

    c10 = stbrett[ciphertext[i+9]];
    c10 = path_lookup[i+9][c10];
    c10 = stbrett[c10];

    c11 = stbrett[ciphertext[i+10]];
    c11 = path_lookup[i+10][c11];
    c11 = stbrett[c11];

    c12 = stbrett[ciphertext[i+11]];
    c12 = path_lookup[i+11][c12];
    c12 = stbrett[c12];

    c13 = stbrett[ciphertext[i+12]];
    c13 = path_lookup[i+12][c13];
    c13 = stbrett[c13];

    c14 = stbrett[ciphertext[i+13]];
    c14 = path_lookup[i+13][c14];
    c14 = stbrett[c14];

    c15 = stbrett[ciphertext[i+14]];
    c15 = path_lookup[i+14][c15];
    c15 = stbrett[c15];

    c16 = stbrett[ciphertext[i+15]];
    c16 = path_lookup[i+15][c16];
    c16 = stbrett[c16];

    f[c1]++;
    f[c2]++;
    f[c3]++;
    f[c4]++;
    f[c5]++;
    f[c6]++;
    f[c7]++;
    f[c8]++;
    f[c9]++;
    f[c10]++;
    f[c11]++;
    f[c12]++;
    f[c13]++;
    f[c14]++;
    f[c15]++;
    f[c16]++;
  }
  for (; i < len-3; i += 4) {
    c1 = stbrett[ciphertext[i]];
    c1 = path_lookup[i][c1];
    c1 = stbrett[c1];

    c2 = stbrett[ciphertext[i+1]];
    c2 = path_lookup[i+1][c2];
    c2 = stbrett[c2];

    c3 = stbrett[ciphertext[i+2]];
    c3 = path_lookup[i+2][c3];
    c3 = stbrett[c3];

    c4 = stbrett[ciphertext[i+3]];
    c4 = path_lookup[i+3][c4];
    c4 = stbrett[c4];

    f[c1]++;
    f[c2]++;
    f[c3]++;
    f[c4]++;
  }
  for (; i < len; i++) {
    c1 = stbrett[ciphertext[i]];
    c1 = path_lookup[i][c1];
    c1 = stbrett[c1];
    f[c1]++;
  }


  S0 = S1 = S2 = S3 = 0;
  for (i = 0; i < 23; i += 4) {
    S0 += f[i]*(f[i]-1);
    S1 += f[i+1]*(f[i+1]-1);
    S2 += f[i+2]*(f[i+2]-1);
    S3 += f[i+3]*(f[i+3]-1);
  }
  S0 += f[24]*(f[24]-1);
  S1 += f[25]*(f[25]-1);

  //return (double)((S0+S1) + (S2+S3)) / (len*(len-1));
  fprintf(stderr, "i/c debug: %i  \n", S0+S1+S2+S3);
  return (double)((S0+S1) + (S2+S3));

}


To jest funkcja, gdzie myślałem o zmianie double na 64 bit integera, bo pamiętałem jeszcze z listy mailingowej M4 wzmianki o ogromnych liczbach jakie tu występują. A tymczasem:

Cytat: icscore
i/c debug: 442  
i/c debug: 454  
i/c debug: 448  
i/c debug: 474  
i/c debug: 438  
i/c debug: 440  
i/c debug: 488  
i/c debug: 506  
i/c debug: 430  
i/c debug: 450  
i/c debug: 426  
i/c debug: 492  
i/c debug: 488  
i/c debug: 476  
i/c debug: 470  
i/c debug: 442  
i/c debug: 408  
i/c debug: 488  
i/c debug: 496  
i/c debug: 462  
i/c debug: 460  
i/c debug: 472  
i/c debug: 476  
i/c debug: 476  
i/c debug: 460  
i/c debug: 462  
i/c debug: 472  
i/c debug: 456  
i/c debug: 464  
i/c debug: 446  
i/c debug: 440  
i/c debug: 464  
i/c debug: 456  
i/c debug: 464  
i/c debug: 440  
i/c debug: 446  
i/c debug: 436  
i/c debug: 424  
i/c debug: 488  
i/c debug: 462  
i/c debug: 436  
i/c debug: 456  
i/c debug: 484  
i/c debug: 472  
i/c debug: 544  
i/c debug: 514  
i/c debug: 516  
i/c debug: 524  
i/c debug: 542  
i/c debug: 556  
i/c debug: 538  
i/c debug: 512  
i/c debug: 524  
i/c debug: 522  
i/c debug: 516  
i/c debug: 520  
i/c debug: 542  
i/c debug: 530  
i/c debug: 532  
i/c debug: 534  
i/c debug: 532  
i/c debug: 510  
i/c debug: 496  
i/c debug: 516  
i/c debug: 480  
i/c debug: 476  
i/c debug: 532  
i/c debug: 510  
i/c debug: 532  
i/c debug: 534  
i/c debug: 558  
i/c debug: 600  
i/c debug: 532  
i/c debug: 538  
i/c debug: 570  
i/c debug: 544  
i/c debug: 596  
i/c debug: 548  
i/c debug: 530  
i/c debug: 574  
i/c debug: 564  
i/c debug: 540  
i/c debug: 536  
i/c debug: 528  
i/c debug: 516  
i/c debug: 534  
i/c debug: 510  
i/c debug: 546  
i/c debug: 592  
i/c debug: 564  
i/c debug: 520  
i/c debug: 508  
i/c debug: 482  
i/c debug: 470  
i/c debug: 570  
i/c debug: 538  
i/c debug: 510  
i/c debug: 546  
i/c debug: 516  
i/c debug: 534  
i/c debug: 516  
i/c debug: 540  
i/c debug: 584  
i/c debug: 590  
i/c debug: 550  
i/c debug: 546  
i/c debug: 496  
i/c debug: 510  
i/c debug: 504  
i/c debug: 490  
i/c debug: 550  
i/c debug: 546  
i/c debug: 584  
i/c debug: 590  
i/c debug: 482  
i/c debug: 470  
i/c debug: 520  
i/c debug: 508

ciekawe, gdzie tkwi haczyk...

Teoretycznie ciphertext może być o wiele dłuższy, ale według podręcznika operatora enigmy, nie wolno bylo przekroczyć chyba koło 300 znaków.


Zastanawiają mnie też porównania tego typu

Kod:
                    if (ic-bestic > DBL_EPSILON) {
                       bestic = ic;
                       action = KZ_IZ;
                     }

Skoro po usunięciu dzielenia, które praktycznie nic nie wnosi (przecież i bez dzielenia lepszy score zawsze będzie lepszy, a gorszy będzie gorszy) liczba mieści się powiedzmy w  1000, to po co użyty typ double i jeszcze takie dziwne porównania  Blink DBL_EPSILON zdefiniowany jest jako 0.000000001.
Zastanawiam się, jakie to może mieć znaczenie dla logiki programu.
Możliwe, że dzielenie ma wnieść jakąś dodatkową zależność score od długości tekstu, ale skoro aplikacja cały czas pracuje na tekście jednej długości, to po co to  Blink Chyba spróbuję to pousuwać razem z tym DBL_EPSILONem i przetestować jak zachowa się aplikacja.
Nie wiem na ile bezpieczne są takie modyfikacje, bo aplikacja może działać poprawnie i zwracać poprawne wyniki, ale jakość hillclimba może spaść na łeb i cały soft nie będzie w stanie nic złamać.
« Ostatnia zmiana: Sierpień 17, 2009, 00:56:25 wysłane przez TJM » Zapisane



Strony: 1 ... 36 37 38 39 [40] 41 42 43   Do góry
  Dodaj zakładkę  |  Drukuj  

 
Skocz do:  

Działa na MySQL Działa na PHP Powered by SMF 1.1.11 | SMF © 2006-2007, Simple Machines LLC
Hosting dzięki uprzejmości InnerVision sp. z o.o.
Prawidłowy XHTML 1.0! Prawidłowy CSS!