🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.c
42 messages
42 total messages Started by M.M. Tue, 24 Dec 2019 19:25
Optymalizacja kodu
#310010
Author: M.M.
Date: Tue, 24 Dec 2019 19:25
360 lines
12534 bytes
Czasami potrzebuję całkowite liczby pseudolosowe z małego 
przedziału, przy czym losowość tychże liczb nie musi być
wysokiej jakości, ale za to generowanie musi być bardzo 
szybkie. Standardowy sposób na uzyskanie takich liczb jest 
zapewne wszystkim czytelnikom tej grupy znany, ale przypomnijmy:

random() % (MAX-MIN+1) + MIN;

Od razu widać zabójczą dla wydajności operację modulo :/ Co
można na to poradzić? Mój pierwszy pomysł był taki, aby zgrać
do tablicy np. milion liczb, a potem z tej tablicy te liczby w
kółko podawać. Cóż może być wydajniejszego, niż podawanie kolejnych
liczb z pamięci RAM? Niestety tablica o rozmiarze miliona elementów
to lekkie marnotrawienie pamięci RAM i nie wiadomo jak procesor
takie tablice będzie buforował w większych programach. Zastosowałem
więc rozwiązanie z użyciem dwóch buforów:

buff1[SIZE1];
buff2[SIZE2];

( albo jednego łączonego buff[SIZE1+SIZE2] )

przy czym SIZE1 i SIZE2 to są liczby pierwsze z przedziału 
około <100,10000>. Można podawać na przemian liczby z bufora1 i 
bufora2, cykl takiego 'generatora' wyniesie size1*size2 (po
wygenerowaniu tylu liczb można bufory zapełnić nowymi liczbami, to
niewiele spowolni generator, bo jest mało generowania w stosunku
do podawanych liczb).

 
No więc teoria jest prosta, pora zabrać się kodowanie. Jednak są niespodzianki.
Generator std::mt19937_64 wygenerował 4mld liczb z przedziału od 11 do 38 w
około 27 sekund. Natomiast ta sztuczka z dwoma tablicami potrzebowała aż
35 sekund! Czyli zamiast przyspieszenia uzyskałem spowolnienie. Implementacja
tej wersji jest w załączonym kodzie na dole w klasie RndBuff1. Nie poddawałem
się, zamiast statycznej tablicy użyłem dynamicznie przydzielonej przez
new - myślę sobie, a może kompilator lepiej da radę z new. Okazało się, że jest
jeszcze gorzej, czas wzrósł do 38s - to jest w klasie RndBuff2. Dopiero jak
dodałem wskaźniki i kilka usprawnień instrukcji warunkowych, czas spadł do...
zaledwie 4 sekund - to jest w klasie RndBuff3. Dla pewności sprawdziłem jeszcze
kombinację z tablicą (zamiast new) i wskaźnikami. Czas z powrotem wzrósł do
11 sekund - kod w RndBuff4. 

Po 34 pomiarach czasu, wyniki wyglądają tak:
seed [911368664458670987] nr.:34
raw mt start   105226567093 872
RndBuff1 start 105232396785 1210
RndBuff2 start 105232396785 1267
RndBuff3 start 105232396785 127
RndBuff4 start 105232396785 397

Widać że czas pomiędzy najlepszą i najgorszą wersją różni się aż 10 razy, a
kod ciągle bardzo podobny i oczywiste optymalizacje spowalniają!

Suma kontrolna z raw mt jest inna, bo też jest inny algorytm generowania - to
nie stanowi błędu.

Niezrozumiałe jest dla mnie, dlaczego są tak duże różnice w czasie przy
tak niewielkich zmianach.

Pouczające jest to, że jeśli już chcemy mieć kawałek wydajnego kodu, to
niewielkie zmiany mogą dawać  10-krotne przyspieszenie. I to, że oczywista
optymalizacja może tak naprawdę spowolnić nasz kod.

Pozdrawiam


Zawsze mogłem popełnić jakieś błędy (choć sumy kontrolne się zgadzają), więc
będę wdzięczny za krytykę:

#include <iostream>
#include <random>
#include <ctime>

using ultyp = unsigned long long;
using utyp  = unsigned int;
using cultyp = const ultyp;
using cutyp  = const utyp;

template<class TRND,cutyp SIZE1, cutyp SIZE2>
class RndBuff1 {
private:
    TRND  &rnd;   // Pseudo random number generator.
    utyp  min;    // Min range.
    utyp  max;    // Max range.
    utyp  buff[SIZE1+SIZE2];   // N-Cyclic buffer to number generator.
    utyp  i1,i2;  // Index to the next given value.
    utyp  select; // Select first or second buffer.

private:
    void reset() {
        for( utyp i=0 ; i<SIZE1+SIZE2 ; i++ ) {
            buff[i] = rnd() % (max-min+1)+min;
        }
    }
public:
    RndBuff1( TRND &rnd, cutyp min=0, cutyp max=0 ) : rnd(rnd) {
        setMinMax(min,max);
    }
    void setMinMax(cutyp min, cutyp max   ) {
        this->min = min;
        this->max = max;
        i1 = SIZE1;
        i2 = SIZE1+SIZE2;
        select = 0;
    }
    utyp operator()() {
        if( i1 == SIZE1 && i2 == SIZE1+SIZE2 ) {
            reset();
        }
        if( 1 & select++ ) {
            if( i1 == SIZE1 ) {
                i1 = 0;
            }
            return buff[i1++];
        }
        if( i2 == SIZE1+SIZE2 ) {
            i2 = SIZE1;
        }
        return buff[i2++];
    }

};

template<class TRND,cutyp SIZE1, cutyp SIZE2>
class RndBuff2 {
private:
    TRND  &rnd;   // Pseudo random number generator.
    utyp  min;    // Min range.
    utyp  max;    // Max range.
    utyp  *const buff;   // N-Cyclic buffer to number generator.
    utyp  i1,i2;  // Index to the next given value.
    utyp  select; // Select first or second buffer.

private:
    void reset() {
        for( utyp i=0 ; i<SIZE1+SIZE2 ; i++ ) {
            buff[i] = rnd() % (max-min+1)+min;
        }
    }
public:
    RndBuff2( TRND &rnd, cutyp min=0, cutyp max=0 ) : rnd(rnd), buff(new utyp[SIZE1+SIZE2]) {
        setMinMax(min,max);
    }
    ~RndBuff2() {
        delete[]buff;
    }
    void setMinMax(cutyp min, cutyp max) {
        this->min = min;
        this->max = max;
        i1 = SIZE1;
        i2 = SIZE1+SIZE2;
        select = 0;
    }
    utyp operator()() {
        if( i1 == SIZE1 && i2 == SIZE1+SIZE2 ) {
            reset();
        }
        if( 1 & select++ ) {
            if( i1 == SIZE1 ) {
                i1 = 0;
            }
            return buff[i1++];
        }
        if( i2 == SIZE1+SIZE2 ) {
            i2 = SIZE1;
        }
        return buff[i2++];
    }

};


template<class TRND,cutyp SIZE1, cutyp SIZE2>
class RndBuff3 {
private:
    TRND  &rnd;   // Pseudo random number generator.
    utyp  min;    // Min range.
    utyp  max;    // Max range.
    utyp  *const buff;  // N-Cyclic buffer to number generator.
    cutyp *i1;          // Index to the next given value.
    cutyp *i2;
    utyp  select; // Select first or second buffer.

private:
    void reset() {
        for( utyp i=0 ; i<SIZE1+SIZE2 ; i++ ) {
            buff[i] = rnd() % (max-min+1)+min;
        }
    }
public:
    RndBuff3( TRND &rnd, cutyp min=0, cutyp max=0 ) : rnd(rnd), buff(new utyp[SIZE1+SIZE2]) {
        setMinMax(min,max);
    }
    ~RndBuff3() {
        delete[] buff;
    }
    void setMinMax(cutyp min, cutyp max) {
        this->min = min;
        this->max = max;
        i1 = buff+SIZE1;
        i2 = buff+SIZE1+SIZE2;
        select = 0;
    }
    utyp operator()() {
        if( 1 & select++ ) {
            if( i1 == buff+SIZE1 ) {
                if( i2 == buff+SIZE1+SIZE2 ) {
                    reset();
                }
                i1 = buff;
            }
            return *i1++;
        } else {
            if( i2 == buff+SIZE1+SIZE2 ) {
                if(i1 == buff+SIZE1) {
                    reset();
                }
                i2 = buff+SIZE1;
            }
            return *i2++;
        }
    }

};


template<class TRND,cutyp SIZE1, cutyp SIZE2>
class RndBuff4 {
private:
    TRND  &rnd;   // Pseudo random number generator.
    utyp  min;    // Min range.
    utyp  max;    // Max range.
    utyp  buff[SIZE1+SIZE2];  // N-Cyclic buffer to number generator.
    cutyp *i1;          // Index to the next given value.
    cutyp *i2;
    utyp  select; // Select first or second buffer.

private:
    void reset() {
        for( utyp i=0 ; i<SIZE1+SIZE2 ; i++ ) {
            buff[i] = rnd() % (max-min+1)+min;
        }
    }
public:
    RndBuff4( TRND &rnd, cutyp min=0, cutyp max=0 ) : rnd(rnd) {
        setMinMax(min,max);
    }
    void setMinMax(cutyp min, cutyp max) {
        this->min = min;
        this->max = max;
        i1 = buff+SIZE1;
        i2 = buff+SIZE1+SIZE2;
        select = 0;
    }
    utyp operator()() {
        if( 1 & select++ ) {
            if( i1 == buff+SIZE1 ) {
                if( i2 == buff+SIZE1+SIZE2 ) {
                    reset();
                }
                i1 = buff;
            }
            return *i1++;
        } else {
            if( i2 == buff+SIZE1+SIZE2 ) {
                if(i1 == buff+SIZE1) {
                    reset();
                }
                i2 = buff+SIZE1;
            }
            return *i2++;
        }
    }

};


constexpr ultyp LOOPS = 1ull << 32;
constexpr utyp  MIN = 11;
constexpr utyp  MAX = 38;
constexpr utyp  SIZE1 = 1249;
constexpr utyp  SIZE2 = 1699;


int main() {
    cultyp mainSeed = 1234567890ull;
    time_t times[5] = {0,0,0,0,0};
    std::mt19937_64 rnd, rndSeed(mainSeed);

    for( utyp test=0 ; true ; test++ ) {
        cultyp seed = rndSeed();
        std::cout << "seed [" << seed << "] nr.:" << (test+1) << std::endl;

        {
            std::cout << "raw mt start   ";
            ultyp sum = 0;
            rnd.seed( seed );
            std::uniform_int_distribution<int> dist(MIN,MAX);
            const time_t start = time(NULL);
            for( ultyp loop=0 ; loop<LOOPS ; loop++ ) {
                sum += dist( rnd );
            }
            times[0] += time(NULL) - start;
            std::cout << sum << " " << times[0] << std::endl;
        }
        {
            std::cout << "RndBuff1 start ";
            ultyp sum = 0;
            rnd.seed( seed );
            RndBuff1<std::mt19937_64,SIZE1,SIZE2> rndBuf(rnd,MIN,MAX);
            const time_t start = time(NULL);
            for( ultyp loop=0 ; loop<LOOPS ; loop++ ) {
                sum += rndBuf();
            }
            times[1] += time(NULL) - start;
            std::cout << sum << " " << times[1] << std::endl;
        }
        {
            std::cout << "RndBuff2 start ";
            ultyp sum = 0;
            rnd.seed( seed );
            RndBuff2<std::mt19937_64,SIZE1,SIZE2> rndBuf(rnd,MIN,MAX);
            const time_t start = time(NULL);
            for( ultyp loop=0 ; loop<LOOPS ; loop++ ) {
                sum += rndBuf();
            }
            times[2] += time(NULL) - start;
            std::cout << sum << " " << times[2] << std::endl;
        }
        {
            std::cout << "RndBuff3 start ";
            ultyp sum = 0;
            rnd.seed( seed );
            RndBuff3<std::mt19937_64,SIZE1,SIZE2> rndBuf(rnd,MIN,MAX);
            const time_t start = time(NULL);
            for( ultyp loop=0 ; loop<LOOPS ; loop++ ) {
                sum += rndBuf();
            }
            times[3] += time(NULL) - start;
            std::cout << sum << " " << times[3] << std::endl;
        }
        {
            std::cout << "RndBuff4 start ";
            ultyp sum = 0;
            rnd.seed( seed );
            RndBuff4<std::mt19937_64,SIZE1,SIZE2> rndBuf(rnd,MIN,MAX);
            const time_t start = time(NULL);
            for( ultyp loop=0 ; loop<LOOPS ; loop++ ) {
                sum += rndBuf();
            }
            times[4] += time(NULL) - start;
            std::cout << sum << " " << times[4] << std::endl;
        }

    }


    return 0;
}
Re: Optymalizacja kodu
#310011
Author: Maciek Godek
Date: Wed, 25 Dec 2019 10:55
17 lines
2833 bytes
W dniu wtorek, 24 grudnia 2019 20:25:33 UTC+1 użytkownik M.M. napisał:
> Czasami potrzebuję całkowite liczby pseudolosowe z małego 
> przedziału, przy czym losowość tychże liczb nie musi być
> wysokiej jakości, ale za to generowanie musi być bardzo 
> szybkie. Standardowy sposób na uzyskanie takich liczb jest 
> zapewne wszystkim czytelnikom tej grupy znany, ale przypomnijmy:
> 
> random() % (MAX-MIN+1) + MIN;
> 
> Od razu widać zabójczą dla wydajności operację modulo :/ Co
> można na to poradzić? 

Jeżeli prawy operand do modulo jest potęgą dwójki, to wykonanie tej operacji to tylko maska bitowa, a więc operacja bardzo tania. Jeżeli nie jest, to pytanie, czy nie można tego zwiększyć do potęgi dwójki. Jeżeli można to świetnie, a jeżeli nie, to można:
- sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
- zbudować tablicę posiadającą tyle elementów, ile jest w najmniejszej potędze dwójki obejmującej zarkes, i przezmapować elementy, które nie mieszczą się w zakresie na takie, które się w zakresie mieszczą

Oczywiście to rozwiązanie też może być kosztowne, bo to dodatkowa warstwa zapośredniczenia, i jeżeli nie będzie się mieścić w cache'u, albo rywalizować o cache z innymi danymi, to bida.
Re: Optymalizacja kodu
#310012
Author: Maciek Godek
Date: Wed, 25 Dec 2019 11:01
8 lines
1889 bytes
W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:

> - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)

Zresztą nawet w C można to sobie zarytmetyzować:

int x = random() & odpowiednia_maska_bitowa;
return x - (x > zakres)*(potęga_dwójki - zakres);
Re: Optymalizacja kodu
#310013
Author: M.M.
Date: Wed, 25 Dec 2019 13:25
45 lines
3634 bytes
On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> 
> > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> 
> Zresztą nawet w C można to sobie zarytmetyzować:
> 
> int x = random() & odpowiednia_maska_bitowa;
> return x - (x > zakres)*(potęga_dwójki - zakres);

Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
optymalizacje, ale na pewno mogą być.

Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:

T& operator()(const size_t i) {
  if( i >= SIZE ) abort();
  return data[i];
}

To działa o 10% szybciej niż gdy mam samo return:

T& operator()(const size_t i) {
  return data[i];
}

Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
abort - wszak to wywołanie znamienne.

Inna sprawa: Zwykle używam std::vector, albo QVector. Czasami gdy chcę 
zoptymalizować kod, to biorę wskaźniki na dane z tych kontenerów, a kontenery
tylko (i aż!) ułatwiają zarządzanie pamięcią i wykonanie operacji które nie
są krytyczne dla wydajności. Ostatnio spróbowałem wziąć wskaźniki z new, z
std::array i z tablicy o stałym rozmiarze normalnie zadeklarowanej w programie.
Wydaje się że to wszystko jest to samo, bo potem operacje są wykonywane na
wskaźnikach. Jednak gdy używam new to program działa najszybciej - znowu nie
rozumiem dlaczego.

Pozdrawiam
Re: Optymalizacja kodu
#310014
Author: Maciek Godek
Date: Wed, 25 Dec 2019 19:52
40 lines
3609 bytes
W dniu środa, 25 grudnia 2019 14:25:07 UTC+1 użytkownik M.M. napisał:
> On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> > W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> > 
> > > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> > 
> > Zresztą nawet w C można to sobie zarytmetyzować:
> > 
> > int x = random() & odpowiednia_maska_bitowa;
> > return x - (x > zakres)*(potęga_dwójki - zakres);
> 
> Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
> operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
> był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
> optymalizacje, ale na pewno mogą być.
> 
> Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
> zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
> szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
> eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
> dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:
> 
> T& operator()(const size_t i) {
>   if( i >= SIZE ) abort();
>   return data[i];
> }
> 
> To działa o 10% szybciej niż gdy mam samo return:
> 
> T& operator()(const size_t i) {
>   return data[i];
> }
> 
> Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
> abort - wszak to wywołanie znamienne.

Ostatnio wrzucałem na pl.comp.programming linka do tej prezentacji:
https://www.youtube.com/watch?v=r-TLSBdHe1A

Obczaj sobie narzędzia od tego gościa, bo może się okazać, że zmiana katalogu, z którego odpalasz program, będzie miała podobny wpływ na wydajność.
Re: Optymalizacja kodu
#310015
Author: M.M.
Date: Wed, 25 Dec 2019 20:49
44 lines
3837 bytes
On Wednesday, December 25, 2019 at 8:52:44 PM UTC+1, Maciek Godek wrote:
> W dniu środa, 25 grudnia 2019 14:25:07 UTC+1 użytkownik M.M. napisał:
> > On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> > > W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> > > 
> > > > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> > > 
> > > Zresztą nawet w C można to sobie zarytmetyzować:
> > > 
> > > int x = random() & odpowiednia_maska_bitowa;
> > > return x - (x > zakres)*(potęga_dwójki - zakres);
> > 
> > Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
> > operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
> > był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
> > optymalizacje, ale na pewno mogą być.
> > 
> > Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
> > zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
> > szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
> > eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
> > dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:
> > 
> > T& operator()(const size_t i) {
> >   if( i >= SIZE ) abort();
> >   return data[i];
> > }
> > 
> > To działa o 10% szybciej niż gdy mam samo return:
> > 
> > T& operator()(const size_t i) {
> >   return data[i];
> > }
> > 
> > Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
> > abort - wszak to wywołanie znamienne.
> 
> Ostatnio wrzucałem na pl.comp.programming linka do tej prezentacji:
> https://www.youtube.com/watch?v=r-TLSBdHe1A
> 
> Obczaj sobie narzędzia od tego gościa, bo może się okazać, że zmiana katalogu, z którego odpalasz program, będzie miała podobny wpływ na wydajność.

Chyba niemożliwe, zmiana katalogu może mieć 10-cio krotny wpływ na wydajność?
Pozdrawiam
Re: Optymalizacja kodu
#310016
Author: Maciek Godek
Date: Wed, 25 Dec 2019 21:49
46 lines
4078 bytes
W dniu środa, 25 grudnia 2019 21:49:10 UTC+1 użytkownik M.M. napisał:
> On Wednesday, December 25, 2019 at 8:52:44 PM UTC+1, Maciek Godek wrote:
> > W dniu środa, 25 grudnia 2019 14:25:07 UTC+1 użytkownik M.M. napisał:
> > > On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> > > > W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> > > > 
> > > > > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> > > > 
> > > > Zresztą nawet w C można to sobie zarytmetyzować:
> > > > 
> > > > int x = random() & odpowiednia_maska_bitowa;
> > > > return x - (x > zakres)*(potęga_dwójki - zakres);
> > > 
> > > Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
> > > operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
> > > był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
> > > optymalizacje, ale na pewno mogą być.
> > > 
> > > Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
> > > zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
> > > szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
> > > eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
> > > dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:
> > > 
> > > T& operator()(const size_t i) {
> > >   if( i >= SIZE ) abort();
> > >   return data[i];
> > > }
> > > 
> > > To działa o 10% szybciej niż gdy mam samo return:
> > > 
> > > T& operator()(const size_t i) {
> > >   return data[i];
> > > }
> > > 
> > > Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
> > > abort - wszak to wywołanie znamienne.
> > 
> > Ostatnio wrzucałem na pl.comp.programming linka do tej prezentacji:
> > https://www.youtube.com/watch?v=r-TLSBdHe1A
> > 
> > Obczaj sobie narzędzia od tego gościa, bo może się okazać, że zmiana katalogu, z którego odpalasz program, będzie miała podobny wpływ na wydajność.
> 
> Chyba niemożliwe, zmiana katalogu może mieć 10-cio krotny wpływ na wydajność?

Wcześniej pisałeś, że o 10% szybciej
Re: Optymalizacja kodu
#310023
Author: (fir)
Date: Thu, 26 Dec 2019 01:01
69 lines
5322 bytes
W dniu wtorek, 24 grudnia 2019 20:25:33 UTC+1 użytkownik M.M. napisał:
> Czasami potrzebuję całkowite liczby pseudolosowe z małego 
> przedziału, przy czym losowość tychże liczb nie musi być
> wysokiej jakości, ale za to generowanie musi być bardzo 
> szybkie. Standardowy sposób na uzyskanie takich liczb jest 
> zapewne wszystkim czytelnikom tej grupy znany, ale przypomnijmy:
> 
> random() % (MAX-MIN+1) + MIN;
> 
> Od razu widać zabójczą dla wydajności operację modulo :/ Co
> można na to poradzić? Mój pierwszy pomysł był taki, aby zgrać
> do tablicy np. milion liczb, a potem z tej tablicy te liczby w
> kółko podawać. Cóż może być wydajniejszego, niż podawanie kolejnych
> liczb z pamięci RAM? Niestety tablica o rozmiarze miliona elementów
> to lekkie marnotrawienie pamięci RAM i nie wiadomo jak procesor
> takie tablice będzie buforował w większych programach. Zastosowałem
> więc rozwiązanie z użyciem dwóch buforów:
> 
> buff1[SIZE1];
> buff2[SIZE2];
> 
> ( albo jednego łączonego buff[SIZE1+SIZE2] )
> 
> przy czym SIZE1 i SIZE2 to są liczby pierwsze z przedziału 
> około <100,10000>. Można podawać na przemian liczby z bufora1 i 
> bufora2, cykl takiego 'generatora' wyniesie size1*size2 (po
> wygenerowaniu tylu liczb można bufory zapełnić nowymi liczbami, to
> niewiele spowolni generator, bo jest mało generowania w stosunku
> do podawanych liczb).
> 
>  
> No więc teoria jest prosta, pora zabrać się kodowanie. Jednak są niespodzianki.
> Generator std::mt19937_64 wygenerował 4mld liczb z przedziału od 11 do 38 w
> około 27 sekund. Natomiast ta sztuczka z dwoma tablicami potrzebowała aż
> 35 sekund! Czyli zamiast przyspieszenia uzyskałem spowolnienie. Implementacja
> tej wersji jest w załączonym kodzie na dole w klasie RndBuff1. Nie poddawałem
> się, zamiast statycznej tablicy użyłem dynamicznie przydzielonej przez
> new - myślę sobie, a może kompilator lepiej da radę z new. Okazało się, że jest
> jeszcze gorzej, czas wzrósł do 38s - to jest w klasie RndBuff2. Dopiero jak
> dodałem wskaźniki i kilka usprawnień instrukcji warunkowych, czas spadł do...
> zaledwie 4 sekund - to jest w klasie RndBuff3. Dla pewności sprawdziłem jeszcze
> kombinację z tablicą (zamiast new) i wskaźnikami. Czas z powrotem wzrósł do
> 11 sekund - kod w RndBuff4. 
> 
> Po 34 pomiarach czasu, wyniki wyglądają tak:
> seed [911368664458670987] nr.:34
> raw mt start   105226567093 872
> RndBuff1 start 105232396785 1210
> RndBuff2 start 105232396785 1267
> RndBuff3 start 105232396785 127
> RndBuff4 start 105232396785 397
> 
> Widać że czas pomiędzy najlepszą i najgorszą wersją różni się aż 10 razy, a
> kod ciągle bardzo podobny i oczywiste optymalizacje spowalniają!
> 
> Suma kontrolna z raw mt jest inna, bo też jest inny algorytm generowania - to
> nie stanowi błędu.
> 
> Niezrozumiałe jest dla mnie, dlaczego są tak duże różnice w czasie przy
> tak niewielkich zmianach.
> 
> Pouczające jest to, że jeśli już chcemy mieć kawałek wydajnego kodu, to
> niewielkie zmiany mogą dawać  10-krotne przyspieszenie. I to, że oczywista
> optymalizacja może tak naprawdę spowolnić nasz kod.
> 

4 sekundy na 4G intow to troche malo, wychodzi 1 nanosekunda na inta, czyli z 3 cykle na inta, byc moze jest to mozliwe jak wiekszosc tej roboty to 1 if i 1 inc czy cos takiego ale trzebby zdizasemblowac i zobazyc co to dokladnie jest (zief)

sam przestalem sie specjalnie przejmowac takimi optymalizacjami po nauczeniu sie samego optymalizowania (tj robilbym je ale glownie w koncowym produkcie byc moze, normalnie to raczej uzywalbym zwyklego randa z modulo, ktory nie jest az tak strasznie wolny, tj pewnie z 10 ns zajmie )
Re: Optymalizacja kodu
#310019
Author: (fir)
Date: Thu, 26 Dec 2019 01:10
52 lines
4203 bytes
W dniu środa, 25 grudnia 2019 14:25:07 UTC+1 użytkownik M.M. napisał:
> On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> > W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> > 
> > > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> > 
> > Zresztą nawet w C można to sobie zarytmetyzować:
> > 
> > int x = random() & odpowiednia_maska_bitowa;
> > return x - (x > zakres)*(potęga_dwójki - zakres);
> 
> Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
> operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
> był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
> optymalizacje, ale na pewno mogą być.
> 
> Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
> zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
> szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
> eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
> dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:
> 
> T& operator()(const size_t i) {
>   if( i >= SIZE ) abort();
>   return data[i];
> }
> 
> To działa o 10% szybciej niż gdy mam samo return:
> 
> T& operator()(const size_t i) {
>   return data[i];
> }
> 
> Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
> abort - wszak to wywołanie znamienne.
> 
> Inna sprawa: Zwykle używam std::vector, albo QVector. Czasami gdy chcę 
> zoptymalizować kod, to biorę wskaźniki na dane z tych kontenerów, a kontenery
> tylko (i aż!) ułatwiają zarządzanie pamięcią i wykonanie operacji które nie
> są krytyczne dla wydajności. Ostatnio spróbowałem wziąć wskaźniki z new, z
> std::array i z tablicy o stałym rozmiarze normalnie zadeklarowanej w programie.
> Wydaje się że to wszystko jest to samo, bo potem operacje są wykonywane na
> wskaźnikach. Jednak gdy używam new to program działa najszybciej - znowu nie
> rozumiem dlaczego.
> 
> Pozdrawiam

testy powinno sie robic raczej w petli, 
tak byto co testowane sie 'rozgrzalo' ;c
(pozatym jak sie mierzy w petli to widac ze wyniki czasem nieco oscyluja od przebiegu do przebiegu (zwykle nie jakos bardzoa le jednak)

 jak ja cos mierze zawsze mierze w petli takim pojedynczym przebiegom bym nie wierzyl - byc moze sa dobre ale nie wiem, bo nigdy ich nie uzywam
Re: Optymalizacja kodu
#310020
Author: (fir)
Date: Thu, 26 Dec 2019 01:18
64 lines
4611 bytes
W dniu czwartek, 26 grudnia 2019 02:10:51 UTC+1 użytkownik (fir) napisał:
> W dniu środa, 25 grudnia 2019 14:25:07 UTC+1 użytkownik M.M. napisał:
> > On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> > > W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> > > 
> > > > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> > > 
> > > Zresztą nawet w C można to sobie zarytmetyzować:
> > > 
> > > int x = random() & odpowiednia_maska_bitowa;
> > > return x - (x > zakres)*(potęga_dwójki - zakres);
> > 
> > Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
> > operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
> > był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
> > optymalizacje, ale na pewno mogą być.
> > 
> > Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
> > zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
> > szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
> > eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
> > dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:
> > 
> > T& operator()(const size_t i) {
> >   if( i >= SIZE ) abort();
> >   return data[i];
> > }
> > 
> > To działa o 10% szybciej niż gdy mam samo return:
> > 
> > T& operator()(const size_t i) {
> >   return data[i];
> > }
> > 
> > Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
> > abort - wszak to wywołanie znamienne.
> > 
> > Inna sprawa: Zwykle używam std::vector, albo QVector. Czasami gdy chcę 
> > zoptymalizować kod, to biorę wskaźniki na dane z tych kontenerów, a kontenery
> > tylko (i aż!) ułatwiają zarządzanie pamięcią i wykonanie operacji które nie
> > są krytyczne dla wydajności. Ostatnio spróbowałem wziąć wskaźniki z new, z
> > std::array i z tablicy o stałym rozmiarze normalnie zadeklarowanej w programie.
> > Wydaje się że to wszystko jest to samo, bo potem operacje są wykonywane na
> > wskaźnikach. Jednak gdy używam new to program działa najszybciej - znowu nie
> > rozumiem dlaczego.
> > 
> > Pozdrawiam
> 
> testy powinno sie robic raczej w petli, 
> tak byto co testowane sie 'rozgrzalo' ;c
> (pozatym jak sie mierzy w petli to widac ze wyniki czasem nieco oscyluja od przebiegu do przebiegu (zwykle nie jakos bardzoa le jednak)
> 
>  jak ja cos mierze zawsze mierze w petli takim pojedynczym przebiegom bym nie wierzyl - byc moze sa dobre ale nie wiem, bo nigdy ich nie uzywam

przy czym w petli mam na mysli pojedyncze testy cos w stylu

for(int i=0;i<10000;i++)
{
  test();
  wyniki[i] = tic();
 
}

a nie 4 zmieszane bo byc moze moga na siebie wplywac
Re: Optymalizacja kodu
#310017
Author: M.M.
Date: Thu, 26 Dec 2019 03:46
105 lines
6605 bytes
On Wednesday, December 25, 2019 at 10:49:29 PM UTC+1, Maciek Godek wrote:
> W dniu środa, 25 grudnia 2019 21:49:10 UTC+1 użytkownik M.M. napisał:
> > On Wednesday, December 25, 2019 at 8:52:44 PM UTC+1, Maciek Godek wrote:
> > > W dniu środa, 25 grudnia 2019 14:25:07 UTC+1 użytkownik M.M. napisał:
> > > > On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> > > > > W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> > > > > 
> > > > > > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> > > > > 
> > > > > Zresztą nawet w C można to sobie zarytmetyzować:
> > > > > 
> > > > > int x = random() & odpowiednia_maska_bitowa;
> > > > > return x - (x > zakres)*(potęga_dwójki - zakres);
> > > > 
> > > > Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
> > > > operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
> > > > był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
> > > > optymalizacje, ale na pewno mogą być.
> > > > 
> > > > Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
> > > > zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
> > > > szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
> > > > eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
> > > > dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:
> > > > 
> > > > T& operator()(const size_t i) {
> > > >   if( i >= SIZE ) abort();
> > > >   return data[i];
> > > > }
> > > > 
> > > > To działa o 10% szybciej niż gdy mam samo return:
> > > > 
> > > > T& operator()(const size_t i) {
> > > >   return data[i];
> > > > }
> > > > 
> > > > Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
> > > > abort - wszak to wywołanie znamienne.
> > > 
> > > Ostatnio wrzucałem na pl.comp.programming linka do tej prezentacji:
> > > https://www.youtube.com/watch?v=r-TLSBdHe1A
> > > 
> > > Obczaj sobie narzędzia od tego gościa, bo może się okazać, że zmiana katalogu, z którego odpalasz program, będzie miała podobny wpływ na wydajność.
> > 
> > Chyba niemożliwe, zmiana katalogu może mieć 10-cio krotny wpływ na wydajność?
> 
> Wcześniej pisałeś, że o 10% szybciej

Pomiędzy wersją najszybszą a najwolniejszą mam 90% lub 1000% - zależy jak 
liczyć. Różnice pomiędzy wersją najszybszą a najwolniejszą są w moim odczuciu
kosmetyczne. NP. są wskaźniki zamiast indeksów:

return *i1++
zamiast
return buff[i1++]

Pamięć bufora jest pobierana z new, zamiast z pierwszego elementu tablicy:

buff = new typ[rozmiar];

zamiast

buff[rozmiar];
buff = &vector[0];

Jest minimalna optymalizacja instrukcji warunkowych.

Dziwi mnie przyspieszenie 10cio krotne z powodu takich niemal kosmetycznych
zmian.

Poza tym jest druga sprawa. Gdy dodaję kod, dokładnie gdy dodaję jedną
instrukcję warunkową:

if( index >= SIZE ) abort(); // Tak tę instrukcję.
return buff[index];

to program zaczął działać o 10% szybciej.

Ale... co ma wspólnego katalog z przyspieszeniem obliczeń na CPU? Swoją drogą,
odpalałem wszystkie testy z tego samego katalogu. 10% na czasie obliczeń
rzędu 100-200 sekund to chyba mierzalna wartość?

Kiedyś czytałem zdanie z którym nie do końca się zgadzam, że genialność języka
C i jego następcy C++ polega na tym, iż można kompilatorowi dzięki wskaźnikom
podpowiedzieć co ma być obliczane i kompilator generuje bardziej efektywny 
kod. Oczywiście w innych językach też można spotkać wskaźniki, a jeśli nie
ma wskaźników, to kompilator ma pewność że dane nie zostały zmienione za pomocą
dostępu przez wskaźniki  i może generować wydajniejszy kod. Przez wiele ostatnich
lat (około 10-12) widziałem, że drobne zmiany w kodzie nie wpływają na wydajność
obliczeń. Czy używałem wskaźnika, czy tablicy i indeksu, czy wektora, czy
makra, czy funkcji inline, czas był z reguły podobny, a nigdy nie był tak 
mocno różny. Ostatnio widzę że z powrotem dzięki kilku drobnym eksperymentom 
cały duży program można przyspieszyć np. dwa razy, a malutką procedurę nawet
10 razy. Co się stało? Używam kompilatora:

g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Pozdrawiam


Pozdrawiam
Re: Optymalizacja kodu
#310024
Author: M.M.
Date: Thu, 26 Dec 2019 04:00
121 lines
6777 bytes
On Thursday, December 26, 2019 at 2:01:35 AM UTC+1, (fir) wrote:
> W dniu wtorek, 24 grudnia 2019 20:25:33 UTC+1 użytkownik M.M. napisał:
> > Czasami potrzebuję całkowite liczby pseudolosowe z małego 
> > przedziału, przy czym losowość tychże liczb nie musi być
> > wysokiej jakości, ale za to generowanie musi być bardzo 
> > szybkie. Standardowy sposób na uzyskanie takich liczb jest 
> > zapewne wszystkim czytelnikom tej grupy znany, ale przypomnijmy:
> > 
> > random() % (MAX-MIN+1) + MIN;
> > 
> > Od razu widać zabójczą dla wydajności operację modulo :/ Co
> > można na to poradzić? Mój pierwszy pomysł był taki, aby zgrać
> > do tablicy np. milion liczb, a potem z tej tablicy te liczby w
> > kółko podawać. Cóż może być wydajniejszego, niż podawanie kolejnych
> > liczb z pamięci RAM? Niestety tablica o rozmiarze miliona elementów
> > to lekkie marnotrawienie pamięci RAM i nie wiadomo jak procesor
> > takie tablice będzie buforował w większych programach. Zastosowałem
> > więc rozwiązanie z użyciem dwóch buforów:
> > 
> > buff1[SIZE1];
> > buff2[SIZE2];
> > 
> > ( albo jednego łączonego buff[SIZE1+SIZE2] )
> > 
> > przy czym SIZE1 i SIZE2 to są liczby pierwsze z przedziału 
> > około <100,10000>. Można podawać na przemian liczby z bufora1 i 
> > bufora2, cykl takiego 'generatora' wyniesie size1*size2 (po
> > wygenerowaniu tylu liczb można bufory zapełnić nowymi liczbami, to
> > niewiele spowolni generator, bo jest mało generowania w stosunku
> > do podawanych liczb).
> > 
> >  
> > No więc teoria jest prosta, pora zabrać się kodowanie. Jednak są niespodzianki.
> > Generator std::mt19937_64 wygenerował 4mld liczb z przedziału od 11 do 38 w
> > około 27 sekund. Natomiast ta sztuczka z dwoma tablicami potrzebowała aż
> > 35 sekund! Czyli zamiast przyspieszenia uzyskałem spowolnienie. Implementacja
> > tej wersji jest w załączonym kodzie na dole w klasie RndBuff1. Nie poddawałem
> > się, zamiast statycznej tablicy użyłem dynamicznie przydzielonej przez
> > new - myślę sobie, a może kompilator lepiej da radę z new. Okazało się, że jest
> > jeszcze gorzej, czas wzrósł do 38s - to jest w klasie RndBuff2. Dopiero jak
> > dodałem wskaźniki i kilka usprawnień instrukcji warunkowych, czas spadł do...
> > zaledwie 4 sekund - to jest w klasie RndBuff3. Dla pewności sprawdziłem jeszcze
> > kombinację z tablicą (zamiast new) i wskaźnikami. Czas z powrotem wzrósł do
> > 11 sekund - kod w RndBuff4. 
> > 
> > Po 34 pomiarach czasu, wyniki wyglądają tak:
> > seed [911368664458670987] nr.:34
> > raw mt start   105226567093 872
> > RndBuff1 start 105232396785 1210
> > RndBuff2 start 105232396785 1267
> > RndBuff3 start 105232396785 127
> > RndBuff4 start 105232396785 397
> > 
> > Widać że czas pomiędzy najlepszą i najgorszą wersją różni się aż 10 razy, a
> > kod ciągle bardzo podobny i oczywiste optymalizacje spowalniają!
> > 
> > Suma kontrolna z raw mt jest inna, bo też jest inny algorytm generowania - to
> > nie stanowi błędu.
> > 
> > Niezrozumiałe jest dla mnie, dlaczego są tak duże różnice w czasie przy
> > tak niewielkich zmianach.
> > 
> > Pouczające jest to, że jeśli już chcemy mieć kawałek wydajnego kodu, to
> > niewielkie zmiany mogą dawać  10-krotne przyspieszenie. I to, że oczywista
> > optymalizacja może tak naprawdę spowolnić nasz kod.
> > 
> 
> 4 sekundy na 4G intow to troche malo, wychodzi 1 nanosekunda na inta, czyli z 3 cykle na inta, byc moze jest to mozliwe jak wiekszosc tej roboty to 1 if i 1 inc czy cos takiego ale trzebby zdizasemblowac i zobazyc co to dokladnie jest (zief)

Zdaję sobie sprawę z tego że mogę mieć jakieś błędy w kodzie i rozumowaniu.
Dlatego wyciągnąłem z całości kodu kilka kluczowych wariantów i ich
kod zamieściłem w poście:
[
seed [911368664458670987] nr.:34
raw mt start   105226567093 872
RndBuff1 start 105232396785 1210
RndBuff2 start 105232396785 1267
RndBuff3 start 105232396785 127
RndBuff4 start 105232396785 397
]

127 / 34 < 4 sekundy.

[
constexpr ultyp LOOPS = 1ull << 32;
]

2^32 > 4mld.


[
            std::cout << "RndBuff3 start ";
            ultyp sum = 0;
            rnd.seed( seed );
            RndBuff3<std::mt19937_64,SIZE1,SIZE2> rndBuf(rnd,MIN,MAX);
            const time_t start = time(NULL);
            for( ultyp loop=0 ; loop<LOOPS ; loop++ ) {
                sum += rndBuf();
            }
            times[3] += time(NULL) - start;
            std::cout << sum << " " << times[3] << std::endl;
]

Wykonuje przez te niecałe 4 sekundy ponad:
12mld inkrementacji
8mld porównań
4mld sumowań
4mld pętli
4mld wyłuskań danych spod wskaźnika
4mld call (albo wstawił inline)
4mld return
4mld operacji bitowych AND


> sam przestalem sie specjalnie przejmowac takimi optymalizacjami po nauczeniu sie samego optymalizowania (tj robilbym je ale glownie w koncowym produkcie byc moze, normalnie to raczej uzywalbym zwyklego randa z modulo, ktory nie jest az tak strasznie wolny, tj pewnie z 10 ns zajmie )

Gdy piszę wspólny kawałek kodu (powiedzmy gdy piszę mikro-bibliotekę) to też
dbam o wydajność. Gdy ma coś w kółko liczyć przez lata (może na kilku
komputerach), to też dbam o wydajność.

Pozdrawiam
Re: Optymalizacja kodu
#310021
Author: M.M.
Date: Thu, 26 Dec 2019 04:03
79 lines
4890 bytes
On Thursday, December 26, 2019 at 2:10:51 AM UTC+1, (fir) wrote:
> W dniu środa, 25 grudnia 2019 14:25:07 UTC+1 użytkownik M.M. napisał:
> > On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> > > W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> > > 
> > > > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> > > 
> > > Zresztą nawet w C można to sobie zarytmetyzować:
> > > 
> > > int x = random() & odpowiednia_maska_bitowa;
> > > return x - (x > zakres)*(potęga_dwójki - zakres);
> > 
> > Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
> > operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
> > był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
> > optymalizacje, ale na pewno mogą być.
> > 
> > Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
> > zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
> > szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
> > eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
> > dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:
> > 
> > T& operator()(const size_t i) {
> >   if( i >= SIZE ) abort();
> >   return data[i];
> > }
> > 
> > To działa o 10% szybciej niż gdy mam samo return:
> > 
> > T& operator()(const size_t i) {
> >   return data[i];
> > }
> > 
> > Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
> > abort - wszak to wywołanie znamienne.
> > 
> > Inna sprawa: Zwykle używam std::vector, albo QVector. Czasami gdy chcę 
> > zoptymalizować kod, to biorę wskaźniki na dane z tych kontenerów, a kontenery
> > tylko (i aż!) ułatwiają zarządzanie pamięcią i wykonanie operacji które nie
> > są krytyczne dla wydajności. Ostatnio spróbowałem wziąć wskaźniki z new, z
> > std::array i z tablicy o stałym rozmiarze normalnie zadeklarowanej w programie.
> > Wydaje się że to wszystko jest to samo, bo potem operacje są wykonywane na
> > wskaźnikach. Jednak gdy używam new to program działa najszybciej - znowu nie
> > rozumiem dlaczego.
> > 
> > Pozdrawiam
> 
> testy powinno sie robic raczej w petli, 
> tak byto co testowane sie 'rozgrzalo' ;c
> (pozatym jak sie mierzy w petli to widac ze wyniki czasem nieco oscyluja od przebiegu do przebiegu (zwykle nie jakos bardzoa le jednak)
> 
>  jak ja cos mierze zawsze mierze w petli takim pojedynczym przebiegom bym nie wierzyl - byc moze sa dobre ale nie wiem, bo nigdy ich nie uzywam

Dla pewności zrobiłem jeszcze jedna pętlę:

czasy[] = {0,0,0....}
while( true ) {
 i = 0;

 start = time();
 test1()
 czasy[i++] += time() - start;

 start = time();
 test2()
 czasy[i++] += time() - start;

 start = time();
 test3()
 czasy[i++] += time() - start;

 ......
}

Sumują się czasy wielu testów wykonywanych na przemian, stan komputera powinien
byś statystycznie taki sam dla wszystkich testów.

Pozdrawiam
Re: Optymalizacja kodu
#310022
Author: (fir)
Date: Thu, 26 Dec 2019 08:43
99 lines
6181 bytes
W dniu czwartek, 26 grudnia 2019 05:03:19 UTC+1 użytkownik M.M. napisał:
> On Thursday, December 26, 2019 at 2:10:51 AM UTC+1, (fir) wrote:
> > W dniu środa, 25 grudnia 2019 14:25:07 UTC+1 użytkownik M.M. napisał:
> > > On Wednesday, December 25, 2019 at 12:01:32 PM UTC+1, Maciek Godek wrote:
> > > > W dniu środa, 25 grudnia 2019 11:55:33 UTC+1 użytkownik Maciek Godek napisał:
> > > > 
> > > > > - sprawdzić, na ile kosztowna będzie instrukcja warunkowa (może być kosztowna, ale nie musi, bo teoretycznie - na Intelu przynajmniej - kompilator może wciągnąć rejest znaczników w wir operacji arytmetycznych, efektywnie nie wykonując instrukcji skoku warunkowego)
> > > > 
> > > > Zresztą nawet w C można to sobie zarytmetyzować:
> > > > 
> > > > int x = random() & odpowiednia_maska_bitowa;
> > > > return x - (x > zakres)*(potęga_dwójki - zakres);
> > > 
> > > Kiedyś ktoś pokazywał kod w asemblerze jak kompilator zoptymalizował właśnie
> > > operację reszty z dzielenia całkowitego. Nie pamiętam szczegółów, ale efekt
> > > był bardzo imponujący. Nie wiem czy w procesory są wbijane tego typu
> > > optymalizacje, ale na pewno mogą być.
> > > 
> > > Teraz mnie zamurowało na widok dużych różnic w czasie z powodu nieznacznych 
> > > zmian w kodzie. Tutaj na forum wrzuciłem tylko cztery przykłady, na 
> > > szybko wyciągnięte z większego kodu. W ogóle zrobiłem więcej podobnych
> > > eksperymentów i zależność wydajności od drobnych zmian w kodzie jest jeszcze
> > > dziwniejsza. Np. gdy mam własnej roboty wektor a w nim test z funkcją abort:
> > > 
> > > T& operator()(const size_t i) {
> > >   if( i >= SIZE ) abort();
> > >   return data[i];
> > > }
> > > 
> > > To działa o 10% szybciej niż gdy mam samo return:
> > > 
> > > T& operator()(const size_t i) {
> > >   return data[i];
> > > }
> > > 
> > > Czyżby kompilator umiał wywnioskować coś o kodzie na podstawie wywołania
> > > abort - wszak to wywołanie znamienne.
> > > 
> > > Inna sprawa: Zwykle używam std::vector, albo QVector. Czasami gdy chcę 
> > > zoptymalizować kod, to biorę wskaźniki na dane z tych kontenerów, a kontenery
> > > tylko (i aż!) ułatwiają zarządzanie pamięcią i wykonanie operacji które nie
> > > są krytyczne dla wydajności. Ostatnio spróbowałem wziąć wskaźniki z new, z
> > > std::array i z tablicy o stałym rozmiarze normalnie zadeklarowanej w programie.
> > > Wydaje się że to wszystko jest to samo, bo potem operacje są wykonywane na
> > > wskaźnikach. Jednak gdy używam new to program działa najszybciej - znowu nie
> > > rozumiem dlaczego.
> > > 
> > > Pozdrawiam
> > 
> > testy powinno sie robic raczej w petli, 
> > tak byto co testowane sie 'rozgrzalo' ;c
> > (pozatym jak sie mierzy w petli to widac ze wyniki czasem nieco oscyluja od przebiegu do przebiegu (zwykle nie jakos bardzoa le jednak)
> > 
> >  jak ja cos mierze zawsze mierze w petli takim pojedynczym przebiegom bym nie wierzyl - byc moze sa dobre ale nie wiem, bo nigdy ich nie uzywam
> 
> Dla pewności zrobiłem jeszcze jedna pętlę:
> 
> czasy[] = {0,0,0....}
> while( true ) {
>  i = 0;
> 
>  start = time();
>  test1()
>  czasy[i++] += time() - start;
> 
>  start = time();
>  test2()
>  czasy[i++] += time() - start;
> 
>  start = time();
>  test3()
>  czasy[i++] += time() - start;
> 
>  ......
> }
> 
> Sumują się czasy wielu testów wykonywanych na przemian, stan komputera powinien
> byś statystycznie taki sam dla wszystkich testów.
> 
> Pozdrawiam

nie uzywam tej funkcji time ale
chodzilo mi raczej o testy typu

for(int i=0;;i++)
{
  for(n=0; n<1000000; n++)
    test1();

  czas[i++] = time();
}

nie che mi sie przygladac dokladnie testom kolegi bo to jest srednio przyjemne a i tak nie wiadomo czy kolega nie ukryl jakichs istotnych czynnikow

pozatym odpowiedz jest chyba jasna co nalezy zrobic? nalezy zdizasemblowac i pokazac kod petli w asmie (dizasemblacja nie jest trudna nawet jakies stronki online pokazuja kod w asmie, nie pamietram juz jakie bo sam uzywam od zasu do czasu jakiegos disasemblera ktory mam na dysku)

pozatym zalezy co to za mala optymalizacja ifow, wlasnie ify zwlaszcza jak nietrafione i na starszych procach moga trwac sporo a na jeszcze starszych podobno az 30 cykli (3 cykle na int daja 1GInt/s gdy 30 cykli daje 100 MIntow/s)

co prawda wlasnie w tej rozmowie z jakims kolesiem na pcp zajrzalem do agnera foga i wyszlo ze na nowych prockach te ify chyba mocno zoptymalizowali
Optymalizacja kodu
#310028
Author: Wojciech Muła
Date: Thu, 26 Dec 2019 08:57
1 lines
1449 bytes
Sprawdź, jak się sprawuje ten algorytm https://lemire.me/blog/2019/07/03/a-fast-16-bit-random-number-generator/
Re: Optymalizacja kodu
#310025
Author: (fir)
Date: Thu, 26 Dec 2019 09:00
20 lines
3009 bytes
W dniu czwartek, 26 grudnia 2019 05:00:06 UTC+1 użytkownik M.M. napisał:
> 
> 
> > sam przestalem sie specjalnie przejmowac takimi optymalizacjami po nauczeniu sie samego optymalizowania (tj robilbym je ale glownie w koncowym produkcie byc moze, normalnie to raczej uzywalbym zwyklego randa z modulo, ktory nie jest az tak strasznie wolny, tj pewnie z 10 ns zajmie )
> 
> Gdy piszę wspólny kawałek kodu (powiedzmy gdy piszę mikro-bibliotekę) to też
> dbam o wydajność. Gdy ma coś w kółko liczyć przez lata (może na kilku
> komputerach), to też dbam o wydajność.
> 

ja do tego tak nie podchodze (tj w finalnym programie do uzywania przez miliony to tak, ale jakos malo pisze finalnych programow raczej prototypy):

jak podchodze:

wg mnie optymalizowania nalezy/warto/trzeba sie nauczyc ale jak sie juz czlowiek go nauczy i jest generalnym programista a nie optymalizatorem to nie warto przesadzac,

bibliotek tez nie optymalizuje bo kwestia jest taka ze ak ktos chce cos porzadnie zoptymalizowac to musi optymalizowac konkretny przypadek co polega glownie na
przepisywaniu i testowaniu i u mnie z reguly taka sesja trwala tydzien roboty i usztywniala kod (np jak pozniej chcesz cos zmienic, rozszerzyc to wypracowana przez tydzien optymalizacja pryska jak banka)

co do liczenia na kompilator to nie od dzis tu bylo pisane (przeze mnie) ze generalnie kompilator nie ma szans z recznym pisaniem bo kompilator nie moze przepisywac kodu (tylko optymalizowac to co jest) a programista ktory  optymalizuje z reki moze przepisywac na dzikie sposoby
Re: Optymalizacja kodu
#310026
Author: (fir)
Date: Thu, 26 Dec 2019 09:05
23 lines
3308 bytes
W dniu czwartek, 26 grudnia 2019 10:00:35 UTC+1 użytkownik (fir) napisał:
> W dniu czwartek, 26 grudnia 2019 05:00:06 UTC+1 użytkownik M.M. napisał:
> > 
> > 
> > > sam przestalem sie specjalnie przejmowac takimi optymalizacjami po nauczeniu sie samego optymalizowania (tj robilbym je ale glownie w koncowym produkcie byc moze, normalnie to raczej uzywalbym zwyklego randa z modulo, ktory nie jest az tak strasznie wolny, tj pewnie z 10 ns zajmie )
> > 
> > Gdy piszę wspólny kawałek kodu (powiedzmy gdy piszę mikro-bibliotekę) to też
> > dbam o wydajność. Gdy ma coś w kółko liczyć przez lata (może na kilku
> > komputerach), to też dbam o wydajność.
> > 
> 
> ja do tego tak nie podchodze (tj w finalnym programie do uzywania przez miliony to tak, ale jakos malo pisze finalnych programow raczej prototypy):
> 
> jak podchodze:
> 
> wg mnie optymalizowania nalezy/warto/trzeba sie nauczyc ale jak sie juz czlowiek go nauczy i jest generalnym programista a nie optymalizatorem to nie warto przesadzac,
> 
> bibliotek tez nie optymalizuje bo kwestia jest taka ze ak ktos chce cos porzadnie zoptymalizowac to musi optymalizowac konkretny przypadek co polega glownie na
> przepisywaniu i testowaniu i u mnie z reguly taka sesja trwala tydzien roboty i usztywniala kod (np jak pozniej chcesz cos zmienic, rozszerzyc to wypracowana przez tydzien optymalizacja pryska jak banka)
> 
> co do liczenia na kompilator to nie od dzis tu bylo pisane (przeze mnie) ze generalnie kompilator nie ma szans z recznym pisaniem bo kompilator nie moze przepisywac kodu (tylko optymalizowac to co jest) a programista ktory  optymalizuje z reki moze przepisywac na dzikie sposoby

proponowal bnym tez napisac wersje tego testu/testow w czystym c i zobazyc i pokazac zrodlo bo na kod w c lepiej mi sie patrzy
Re: Optymalizacja kodu
#310027
Author: (fir)
Date: Thu, 26 Dec 2019 09:12
28 lines
4089 bytes
W dniu czwartek, 26 grudnia 2019 10:05:08 UTC+1 użytkownik (fir) napisał:
> W dniu czwartek, 26 grudnia 2019 10:00:35 UTC+1 użytkownik (fir) napisał:
> > W dniu czwartek, 26 grudnia 2019 05:00:06 UTC+1 użytkownik M.M. napisał:
> > > 
> > > 
> > > > sam przestalem sie specjalnie przejmowac takimi optymalizacjami po nauczeniu sie samego optymalizowania (tj robilbym je ale glownie w koncowym produkcie byc moze, normalnie to raczej uzywalbym zwyklego randa z modulo, ktory nie jest az tak strasznie wolny, tj pewnie z 10 ns zajmie )
> > > 
> > > Gdy piszę wspólny kawałek kodu (powiedzmy gdy piszę mikro-bibliotekę) to też
> > > dbam o wydajność. Gdy ma coś w kółko liczyć przez lata (może na kilku
> > > komputerach), to też dbam o wydajność.
> > > 
> > 
> > ja do tego tak nie podchodze (tj w finalnym programie do uzywania przez miliony to tak, ale jakos malo pisze finalnych programow raczej prototypy):
> > 
> > jak podchodze:
> > 
> > wg mnie optymalizowania nalezy/warto/trzeba sie nauczyc ale jak sie juz czlowiek go nauczy i jest generalnym programista a nie optymalizatorem to nie warto przesadzac,
> > 
> > bibliotek tez nie optymalizuje bo kwestia jest taka ze ak ktos chce cos porzadnie zoptymalizowac to musi optymalizowac konkretny przypadek co polega glownie na
> > przepisywaniu i testowaniu i u mnie z reguly taka sesja trwala tydzien roboty i usztywniala kod (np jak pozniej chcesz cos zmienic, rozszerzyc to wypracowana przez tydzien optymalizacja pryska jak banka)
> > 
> > co do liczenia na kompilator to nie od dzis tu bylo pisane (przeze mnie) ze generalnie kompilator nie ma szans z recznym pisaniem bo kompilator nie moze przepisywac kodu (tylko optymalizowac to co jest) a programista ktory  optymalizuje z reki moze przepisywac na dzikie sposoby
> 
> proponowal bnym tez napisac wersje tego testu/testow w czystym c i zobazyc i pokazac zrodlo bo na kod w c lepiej mi sie patrzy

do tego mozna dodac ze c++ jednak nie idzie tak w parze z optymalizowaniem jak c bo np c++ pociaga za soba zaleznosc od swoich dllek, a optymalizowanie to tez optymalizowanie na rozmiar i na 'niezaleznosc' od innnych komponentow

do tego nei pisze w c++ ale c++ potrafi jednak dodawac jakis glupi crap czyli jakies mutexy tu albo uwdzie itd i jest troche mniej przejrzysty w tym wszystkim imo (choc do kompilatorow c jak gcc tez w sumie nie mam dzis zaufania bo nieststy pisza to ci sami ludzie ktorzy chyab zatracili juz stara cnote dbania o to by rzeczy byly pierwotnie proste i czyste)
Re: Optymalizacja kodu
#310018
Author: Maciek Godek
Date: Thu, 26 Dec 2019 10:14
26 lines
2921 bytes
W dniu czwartek, 26 grudnia 2019 04:46:20 UTC+1 użytkownik M.M. napisał:
> Jest minimalna optymalizacja instrukcji warunkowych.
> 
> Dziwi mnie przyspieszenie 10cio krotne z powodu takich niemal kosmetycznych
> zmian.
> 
> Poza tym jest druga sprawa. Gdy dodaję kod, dokładnie gdy dodaję jedną
> instrukcję warunkową:
> 
> if( index >= SIZE ) abort(); // Tak tę instrukcję.
> return buff[index];
> 
> to program zaczął działać o 10% szybciej.
> 
> Ale... co ma wspólnego katalog z przyspieszeniem obliczeń na CPU? Swoją drogą,
> odpalałem wszystkie testy z tego samego katalogu. 10% na czasie obliczeń
> rzędu 100-200 sekund to chyba mierzalna wartość?

Katalog to akurat jeden z bardziej absurdalnych przykładów.

Jak byś obejrzał prezentację, to bym nie musiał tego tutaj pisać, ale
chodzi o rozmieszczenie obiektów w pamięci podczas uruchomienia, którego
wpływ na wydajność może sięgać 40%.

Prezentacja to wyjaśnia dość szczegółowo (i daje referencje do odpowiednich
pejperów). Facet włożył sporo roboty w tworzenie narzędzi do mierzenia wydajności w sposób nieobciążony rozmieszczeniem obiektów w pamięci.
Re: Optymalizacja kodu
#310029
Author: M.M.
Date: Fri, 27 Dec 2019 06:28
5 lines
1634 bytes
On Thursday, December 26, 2019 at 9:57:09 AM UTC+1, Wojciech Muła wrote:
> Sprawdź, jak się sprawuje ten algorytm https://lemire.me/blog/2019/07/03/a-fast-16-bit-random-number-generator/

Sprawdzę, ale to trochę potrwa, dodam do regularnych testów.
Pozdrawiam
Re: Optymalizacja kodu
#310030
Author: M.M.
Date: Fri, 27 Dec 2019 07:44
169 lines
8068 bytes
On Thursday, December 26, 2019 at 9:57:09 AM UTC+1, Wojciech Muła wrote:
> Sprawdź, jak się sprawuje ten algorytm https://lemire.me/blog/2019/07/03/a-fast-16-bit-random-number-generator/

Mam pytanie, czy można mieć kod tego generatora w swoich programach? Jest
jakaś licencja?

Pierwsza uwaga: zdecydowałem się brać 16 bitów z tego generatora, jakby
brać 32 bity to powinien być dwa razy szybszy, ale nie wiem jak z 
jakością generowanych liczb:

Z takich testów na kolanie wynika, że generowanie 2^34 liczb tym
generatorem zajmuje (w moim środowisku, w mojej implementacji) 
niecałe 53 sekundy:

time ./MRndCPP 
1187849313
1737517433
2503948343
1106027281
4156358698
3197141134
216794925334129

real    0m52.735s
user    0m52.678s
sys     0m0.044s


Dla porównania standardowa implementacja generatora MT19937_64
zajmuje niecałe 101 sekund (w tych samych warunkach):

time ./MRndCPP 
655014610
3386838144
192173729
1854295942
901277944
864046005
271149186579787

real    1m40.958s
user    1m40.701s
sys     0m0.220s


Kilka testów z diehardera zaliczył:

time ./MRndCPP | dieharder -g200 -a -k2        
#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
   rng_name    |rands/second|   Seed   |
stdin_input_raw|  4.05e+07  |3620339557|
#=============================================================================#
        test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
   diehard_birthdays|   0|       100|     100|0.28928174|  PASSED  
      diehard_operm5|   0|   1000000|     100|0.92947482|  PASSED  
  diehard_rank_32x32|   0|     40000|     100|0.09239713|  PASSED  
    diehard_rank_6x8|   0|    100000|     100|0.10209052|  PASSED  
   diehard_bitstream|   0|   2097152|     100|0.51264249|  PASSED  
        diehard_opso|   0|   2097152|     100|0.58815248|  PASSED  
        diehard_oqso|   0|   2097152|     100|0.24822190|  PASSED  
         diehard_dna|   0|   2097152|     100|0.06963961|  PASSED  
diehard_count_1s_str|   0|    256000|     100|0.85895222|  PASSED  
diehard_count_1s_byt|   0|    256000|     100|0.99856981|   WEAK   
 diehard_parking_lot|   0|     12000|     100|0.28041223|  PASSED  
    diehard_2dsphere|   2|      8000|     100|0.97118447|  PASSED  
    diehard_3dsphere|   3|      4000|     100|0.14383896|  PASSED  
     diehard_squeeze|   0|    100000|     100|0.58457683|  PASSED  
        diehard_sums|   0|       100|     100|0.97203656|  PASSED  
        diehard_runs|   0|    100000|     100|0.20272162|  PASSED  
        diehard_runs|   0|    100000|     100|0.08707306|  PASSED  
       diehard_craps|   0|    200000|     100|0.55675752|  PASSED  
       diehard_craps|   0|    200000|     100|0.09543829|  PASSED  
^C

real    3m20.230s
user    3m27.124s
sys     0m9.833s


Druga seria:

time ./MRndCPP | dieharder -g200 -a -k2
#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
   rng_name    |rands/second|   Seed   |
stdin_input_raw|  4.22e+07  |2165006581|
#=============================================================================#
        test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
   diehard_birthdays|   0|       100|     100|0.55410893|  PASSED  
      diehard_operm5|   0|   1000000|     100|0.59858393|  PASSED  
  diehard_rank_32x32|   0|     40000|     100|0.64476682|  PASSED  
    diehard_rank_6x8|   0|    100000|     100|0.58918209|  PASSED  
   diehard_bitstream|   0|   2097152|     100|0.15585271|  PASSED  
        diehard_opso|   0|   2097152|     100|0.83986652|  PASSED  
        diehard_oqso|   0|   2097152|     100|0.33147055|  PASSED  
         diehard_dna|   0|   2097152|     100|0.57772809|  PASSED  
diehard_count_1s_str|   0|    256000|     100|0.35450456|  PASSED  
diehard_count_1s_byt|   0|    256000|     100|0.56128063|  PASSED  
 diehard_parking_lot|   0|     12000|     100|0.91059716|  PASSED  
    diehard_2dsphere|   2|      8000|     100|0.20089094|  PASSED  
    diehard_3dsphere|   3|      4000|     100|0.83251195|  PASSED  
     diehard_squeeze|   0|    100000|     100|0.98232982|  PASSED  
        diehard_sums|   0|       100|     100|0.03112434|  PASSED  
        diehard_runs|   0|    100000|     100|0.14326371|  PASSED  
        diehard_runs|   0|    100000|     100|0.85723327|  PASSED  
       diehard_craps|   0|    200000|     100|0.06862104|  PASSED  
       diehard_craps|   0|    200000|     100|0.91890513|  PASSED  
^C

real    4m3.343s
user    4m12.231s
sys     0m11.024s

Pobieżne testy z practrand też przechodzi:
time ./MRndCPP | ../../PractRand/RNG_test stdin
RNG_test using PractRand version 0.93
RNG = RNG_stdin, seed = 0xf0ae5889
test set = normal, folding = standard(unknown format)

rng=RNG_stdin, seed=0xf0ae5889
length= 128 megabytes (2^27 bytes), time= 2.6 seconds
  no anomalies in 151 test result(s)

rng=RNG_stdin, seed=0xf0ae5889
length= 256 megabytes (2^28 bytes), time= 6.0 seconds
  no anomalies in 162 test result(s)

rng=RNG_stdin, seed=0xf0ae5889
length= 512 megabytes (2^29 bytes), time= 11.7 seconds
  no anomalies in 171 test result(s)

rng=RNG_stdin, seed=0xf0ae5889
length= 1 gigabyte (2^30 bytes), time= 23.2 seconds
  no anomalies in 183 test result(s)

rng=RNG_stdin, seed=0xf0ae5889
length= 2 gigabytes (2^31 bytes), time= 46.2 seconds
  no anomalies in 194 test result(s)

rng=RNG_stdin, seed=0xf0ae5889
length= 4 gigabytes (2^32 bytes), time= 87.7 seconds
  no anomalies in 203 test result(s)

rng=RNG_stdin, seed=0xf0ae5889
length= 8 gigabytes (2^33 bytes), time= 171 seconds
  Test Name                         Raw       Processed     Evaluation
  BCFN(2+2,13-0,T)                  R=  -8.3  p =1-2.4e-4   unusual          
  ...and 214 test result(s) without anomalies

rng=RNG_stdin, seed=0xf0ae5889
length= 16 gigabytes (2^34 bytes), time= 340 seconds
  no anomalies in 226 test result(s)

^C

real    5m46.927s
user    5m43.989s
sys     0m12.371s


Na lepsze testy trzeba poczekać, chyba że z powodu licencji będę musiał 
wyrzucić to ze swojego zestawu generatorów.

Pozdrawiam
Re: Optymalizacja kodu
#310031
Author: (fir)
Date: Fri, 27 Dec 2019 18:48
172 lines
8594 bytes
W dniu piątek, 27 grudnia 2019 08:45:01 UTC+1 użytkownik M.M. napisał:
> On Thursday, December 26, 2019 at 9:57:09 AM UTC+1, Wojciech Muła wrote:
> > Sprawdź, jak się sprawuje ten algorytm https://lemire.me/blog/2019/07/03/a-fast-16-bit-random-number-generator/
> 
> Mam pytanie, czy można mieć kod tego generatora w swoich programach? Jest
> jakaś licencja?
> 
> Pierwsza uwaga: zdecydowałem się brać 16 bitów z tego generatora, jakby
> brać 32 bity to powinien być dwa razy szybszy, ale nie wiem jak z 
> jakością generowanych liczb:
> 
> Z takich testów na kolanie wynika, że generowanie 2^34 liczb tym
> generatorem zajmuje (w moim środowisku, w mojej implementacji) 
> niecałe 53 sekundy:
> 
> time ./MRndCPP 
> 1187849313
> 1737517433
> 2503948343
> 1106027281
> 4156358698
> 3197141134
> 216794925334129
> 
> real    0m52.735s
> user    0m52.678s
> sys     0m0.044s
> 
> 
> Dla porównania standardowa implementacja generatora MT19937_64
> zajmuje niecałe 101 sekund (w tych samych warunkach):
> 
> time ./MRndCPP 
> 655014610
> 3386838144
> 192173729
> 1854295942
> 901277944
> 864046005
> 271149186579787
> 
> real    1m40.958s
> user    1m40.701s
> sys     0m0.220s
> 
> 
> Kilka testów z diehardera zaliczył:
> 
> time ./MRndCPP | dieharder -g200 -a -k2        
> #=============================================================================#
> #            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
> #=============================================================================#
>    rng_name    |rands/second|   Seed   |
> stdin_input_raw|  4.05e+07  |3620339557|
> #=============================================================================#
>         test_name   |ntup| tsamples |psamples|  p-value |Assessment
> #=============================================================================#
>    diehard_birthdays|   0|       100|     100|0.28928174|  PASSED  
>       diehard_operm5|   0|   1000000|     100|0.92947482|  PASSED  
>   diehard_rank_32x32|   0|     40000|     100|0.09239713|  PASSED  
>     diehard_rank_6x8|   0|    100000|     100|0.10209052|  PASSED  
>    diehard_bitstream|   0|   2097152|     100|0.51264249|  PASSED  
>         diehard_opso|   0|   2097152|     100|0.58815248|  PASSED  
>         diehard_oqso|   0|   2097152|     100|0.24822190|  PASSED  
>          diehard_dna|   0|   2097152|     100|0.06963961|  PASSED  
> diehard_count_1s_str|   0|    256000|     100|0.85895222|  PASSED  
> diehard_count_1s_byt|   0|    256000|     100|0.99856981|   WEAK   
>  diehard_parking_lot|   0|     12000|     100|0.28041223|  PASSED  
>     diehard_2dsphere|   2|      8000|     100|0.97118447|  PASSED  
>     diehard_3dsphere|   3|      4000|     100|0.14383896|  PASSED  
>      diehard_squeeze|   0|    100000|     100|0.58457683|  PASSED  
>         diehard_sums|   0|       100|     100|0.97203656|  PASSED  
>         diehard_runs|   0|    100000|     100|0.20272162|  PASSED  
>         diehard_runs|   0|    100000|     100|0.08707306|  PASSED  
>        diehard_craps|   0|    200000|     100|0.55675752|  PASSED  
>        diehard_craps|   0|    200000|     100|0.09543829|  PASSED  
> ^C
> 
> real    3m20.230s
> user    3m27.124s
> sys     0m9.833s
> 
> 
> Druga seria:
> 
> time ./MRndCPP | dieharder -g200 -a -k2
> #=============================================================================#
> #            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
> #=============================================================================#
>    rng_name    |rands/second|   Seed   |
> stdin_input_raw|  4.22e+07  |2165006581|
> #=============================================================================#
>         test_name   |ntup| tsamples |psamples|  p-value |Assessment
> #=============================================================================#
>    diehard_birthdays|   0|       100|     100|0.55410893|  PASSED  
>       diehard_operm5|   0|   1000000|     100|0.59858393|  PASSED  
>   diehard_rank_32x32|   0|     40000|     100|0.64476682|  PASSED  
>     diehard_rank_6x8|   0|    100000|     100|0.58918209|  PASSED  
>    diehard_bitstream|   0|   2097152|     100|0.15585271|  PASSED  
>         diehard_opso|   0|   2097152|     100|0.83986652|  PASSED  
>         diehard_oqso|   0|   2097152|     100|0.33147055|  PASSED  
>          diehard_dna|   0|   2097152|     100|0.57772809|  PASSED  
> diehard_count_1s_str|   0|    256000|     100|0.35450456|  PASSED  
> diehard_count_1s_byt|   0|    256000|     100|0.56128063|  PASSED  
>  diehard_parking_lot|   0|     12000|     100|0.91059716|  PASSED  
>     diehard_2dsphere|   2|      8000|     100|0.20089094|  PASSED  
>     diehard_3dsphere|   3|      4000|     100|0.83251195|  PASSED  
>      diehard_squeeze|   0|    100000|     100|0.98232982|  PASSED  
>         diehard_sums|   0|       100|     100|0.03112434|  PASSED  
>         diehard_runs|   0|    100000|     100|0.14326371|  PASSED  
>         diehard_runs|   0|    100000|     100|0.85723327|  PASSED  
>        diehard_craps|   0|    200000|     100|0.06862104|  PASSED  
>        diehard_craps|   0|    200000|     100|0.91890513|  PASSED  
> ^C
> 
> real    4m3.343s
> user    4m12.231s
> sys     0m11.024s
> 
> Pobieżne testy z practrand też przechodzi:
> time ./MRndCPP | ../../PractRand/RNG_test stdin
> RNG_test using PractRand version 0.93
> RNG = RNG_stdin, seed = 0xf0ae5889
> test set = normal, folding = standard(unknown format)
> 
> rng=RNG_stdin, seed=0xf0ae5889
> length= 128 megabytes (2^27 bytes), time= 2.6 seconds
>   no anomalies in 151 test result(s)
> 
> rng=RNG_stdin, seed=0xf0ae5889
> length= 256 megabytes (2^28 bytes), time= 6.0 seconds
>   no anomalies in 162 test result(s)
> 
> rng=RNG_stdin, seed=0xf0ae5889
> length= 512 megabytes (2^29 bytes), time= 11.7 seconds
>   no anomalies in 171 test result(s)
> 
> rng=RNG_stdin, seed=0xf0ae5889
> length= 1 gigabyte (2^30 bytes), time= 23.2 seconds
>   no anomalies in 183 test result(s)
> 
> rng=RNG_stdin, seed=0xf0ae5889
> length= 2 gigabytes (2^31 bytes), time= 46.2 seconds
>   no anomalies in 194 test result(s)
> 
> rng=RNG_stdin, seed=0xf0ae5889
> length= 4 gigabytes (2^32 bytes), time= 87.7 seconds
>   no anomalies in 203 test result(s)
> 
> rng=RNG_stdin, seed=0xf0ae5889
> length= 8 gigabytes (2^33 bytes), time= 171 seconds
>   Test Name                         Raw       Processed     Evaluation
>   BCFN(2+2,13-0,T)                  R=  -8.3  p =1-2.4e-4   unusual          
>   ...and 214 test result(s) without anomalies
> 
> rng=RNG_stdin, seed=0xf0ae5889
> length= 16 gigabytes (2^34 bytes), time= 340 seconds
>   no anomalies in 226 test result(s)
> 
> ^C
> 
> real    5m46.927s
> user    5m43.989s
> sys     0m12.371s
> 
> 
> Na lepsze testy trzeba poczekać, chyba że z powodu licencji będę musiał 
> wyrzucić to ze swojego zestawu generatorów.
> 
> Pozdrawiam

a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
Re: Optymalizacja kodu
#310032
Author: M.M.
Date: Fri, 27 Dec 2019 19:12
10 lines
1974 bytes
On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo

Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
wyjaśnienie, to chyba nic mi z tego.

Pozdrawiam
Re: Optymalizacja kodu
#310033
Author: (fir)
Date: Fri, 27 Dec 2019 19:18
13 lines
2348 bytes
W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> 
> Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> wyjaśnienie, to chyba nic mi z tego.
> 
> Pozdrawiam

chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
Re: Optymalizacja kodu
#310034
Author: M.M.
Date: Fri, 27 Dec 2019 20:54
22 lines
2866 bytes
On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > 
> > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > wyjaśnienie, to chyba nic mi z tego.
> > 
> > Pozdrawiam
> 
> chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)

Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
chyba nie wyniesie z tego żadnej nauki?

Pozdrawiam
Re: Optymalizacja kodu
#310035
Author: (fir)
Date: Fri, 27 Dec 2019 21:01
23 lines
3216 bytes
W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > 
> > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > wyjaśnienie, to chyba nic mi z tego.
> > > 
> > > Pozdrawiam
> > 
> > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> 
> Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> chyba nie wyniesie z tego żadnej nauki?
> 
jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
Re: Optymalizacja kodu
#310036
Author: M.M.
Date: Sat, 28 Dec 2019 02:44
38 lines
3804 bytes
On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > 
> > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > wyjaśnienie, to chyba nic mi z tego.
> > > > 
> > > > Pozdrawiam
> > > 
> > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > 
> > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > chyba nie wyniesie z tego żadnej nauki?
> > 
> jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki

Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
problemu, to tylko dodanie opcji -S do kompilatora:

https://pastebin.com/xriqX0SS

Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:

movabsq	$6364136223846793005

Pozdrawiam

Pozdrawiam
Re: Optymalizacja kodu
#310037
Author: (fir)
Date: Sat, 28 Dec 2019 09:11
67 lines
5685 bytes
W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > 
> > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > 
> > > > > Pozdrawiam
> > > > 
> > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > 
> > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > chyba nie wyniesie z tego żadnej nauki?
> > > 
> > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> 
> Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> problemu, to tylko dodanie opcji -S do kompilatora:
> 
> https://pastebin.com/xriqX0SS
> 
> Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> 
> movabsq	$6364136223846793005
> 
> Pozdrawiam
> 
> Pozdrawiam

potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
(najlepiej w tej normalnej skladni a nie w tej i z komentarzami)

tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie

widac ze np jedna z oimawianych petli jest 

.L76:
    movl    28832(%rsp), %eax   # rndBuf.select, D.82123
    leal    1(%rax), %edx   #, tmp522
    testb   $1, %al #, D.82123
    movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
    jne .L138   #,
    movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
    cmpq    %r14, %rbp  # tmp566, D.82124
    je  .L139   #,
.L72:
    leaq    4(%rbp), %rax   #, tmp555
    movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
    movl    0(%rbp), %eax   # *_756,
    addq    %rax, %r13  # D.82120, sum
    subq    $1, %r12    #, D.82120
    jne .L76    #,
.L137:


ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
Re: Optymalizacja kodu
#310038
Author: (fir)
Date: Sat, 28 Dec 2019 09:26
70 lines
6153 bytes
W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > 
> > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > 
> > > > > > Pozdrawiam
> > > > > 
> > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > 
> > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > chyba nie wyniesie z tego żadnej nauki?
> > > > 
> > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > 
> > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > problemu, to tylko dodanie opcji -S do kompilatora:
> > 
> > https://pastebin.com/xriqX0SS
> > 
> > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > 
> > movabsq	$6364136223846793005
> > 
> > Pozdrawiam
> > 
> > Pozdrawiam
> 
> potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> 
> tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> 
> widac ze np jedna z oimawianych petli jest 
> 
> .L76:
>     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
>     leal    1(%rax), %edx   #, tmp522
>     testb   $1, %al #, D.82123
>     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
>     jne .L138   #,
>     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
>     cmpq    %r14, %rbp  # tmp566, D.82124
>     je  .L139   #,
> .L72:
>     leaq    4(%rbp), %rax   #, tmp555
>     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
>     movl    0(%rbp), %eax   # *_756,
>     addq    %rax, %r13  # D.82120, sum
>     subq    $1, %r12    #, D.82120
>     jne .L76    #,
> .L137:
> 
> 
> ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa

testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich
Re: Optymalizacja kodu
#310039
Author: M.M.
Date: Sat, 28 Dec 2019 10:50
81 lines
6889 bytes
On Saturday, December 28, 2019 at 10:26:57 AM UTC+1, (fir) wrote:
> W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > 
> > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > 
> > > > > > > Pozdrawiam
> > > > > > 
> > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > 
> > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > 
> > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > 
> > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > 
> > > https://pastebin.com/xriqX0SS
> > > 
> > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > 
> > > movabsq	$6364136223846793005
> > > 
> > > Pozdrawiam
> > > 
> > > Pozdrawiam
> > 
> > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > 
> > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > 
> > widac ze np jedna z oimawianych petli jest 
> > 
> > .L76:
> >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> >     leal    1(%rax), %edx   #, tmp522
> >     testb   $1, %al #, D.82123
> >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> >     jne .L138   #,
> >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> >     cmpq    %r14, %rbp  # tmp566, D.82124
> >     je  .L139   #,
> > .L72:
> >     leaq    4(%rbp), %rax   #, tmp555
> >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> >     movl    0(%rbp), %eax   # *_756,
> >     addq    %rax, %r13  # D.82120, sum
> >     subq    $1, %r12    #, D.82120
> >     jne .L76    #,
> > .L137:
> > 
> > 
> > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> 
> testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich

Nadal nie rozumiem jakie korzyści z analizy asemblera będę miał jako 
programista C++. Kiedyś byle jak napisana procedura w AMS działała 3
razy szybciej niż porządnie napisana w C i z 5 razy szybciej niż w C++.
Ale te czasy minęły, teraz trzeba bardzo dużo pracy włożyć aby czasami
pokonać kompilator o parę procent. Ja raczej bym chciał lepiej wiedzieć 
jak pisać w C++ aby kompilator generował efektywny kod przy zachowaniu 
chociaż minimalnej przejrzystości kodu i podatności na rozbudowę. 

Pozdrawiam
Re: Optymalizacja kodu
#310048
Author: (fir)
Date: Sat, 28 Dec 2019 10:50
73 lines
6804 bytes
W dniu sobota, 28 grudnia 2019 10:26:57 UTC+1 użytkownik (fir) napisał:
> W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > 
> > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > 
> > > > > > > Pozdrawiam
> > > > > > 
> > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > 
> > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > 
> > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > 
> > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > 
> > > https://pastebin.com/xriqX0SS
> > > 
> > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > 
> > > movabsq	$6364136223846793005
> > > 
> > > Pozdrawiam
> > > 
> > > Pozdrawiam
> > 
> > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > 
> > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > 
> > widac ze np jedna z oimawianych petli jest 
> > 
> > .L76:
> >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> >     leal    1(%rax), %edx   #, tmp522
> >     testb   $1, %al #, D.82123
> >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> >     jne .L138   #,
> >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> >     cmpq    %r14, %rbp  # tmp566, D.82124
> >     je  .L139   #,
> > .L72:
> >     leaq    4(%rbp), %rax   #, tmp555
> >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> >     movl    0(%rbp), %eax   # *_756,
> >     addq    %rax, %r13  # D.82120, sum
> >     subq    $1, %r12    #, D.82120
> >     jne .L76    #,
> > .L137:
> > 
> > 
> > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> 
> testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich

sam moglbym poradzic wiecej zanalizowac twoj kod zanalizowac ten asm, ale szczerze mowiac ostatnio nie mam sily sie wczuwac, glownie przez toz e wogole malo sie zajmoje kodowanie, dwa ze te tematy mam opanowane i nie czuje wiekszej potrzeby inwestowania w nie czasu, trzy ze wczuwac sie w czyjs kod i mikrokoncepcje napisania czegos jest troche nudne (a nie che mi sie wczuc i zastanowic czy ten pomysl z dwoma buforami ma sens)
Re: Optymalizacja kodu
#310040
Author: (fir)
Date: Sat, 28 Dec 2019 10:52
84 lines
7310 bytes
W dniu sobota, 28 grudnia 2019 11:50:11 UTC+1 użytkownik M.M. napisał:
> On Saturday, December 28, 2019 at 10:26:57 AM UTC+1, (fir) wrote:
> > W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > > 
> > > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > > 
> > > > > > > > Pozdrawiam
> > > > > > > 
> > > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > > 
> > > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > > 
> > > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > > 
> > > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > > 
> > > > https://pastebin.com/xriqX0SS
> > > > 
> > > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > > 
> > > > movabsq	$6364136223846793005
> > > > 
> > > > Pozdrawiam
> > > > 
> > > > Pozdrawiam
> > > 
> > > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > > 
> > > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > > 
> > > widac ze np jedna z oimawianych petli jest 
> > > 
> > > .L76:
> > >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> > >     leal    1(%rax), %edx   #, tmp522
> > >     testb   $1, %al #, D.82123
> > >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> > >     jne .L138   #,
> > >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> > >     cmpq    %r14, %rbp  # tmp566, D.82124
> > >     je  .L139   #,
> > > .L72:
> > >     leaq    4(%rbp), %rax   #, tmp555
> > >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> > >     movl    0(%rbp), %eax   # *_756,
> > >     addq    %rax, %r13  # D.82120, sum
> > >     subq    $1, %r12    #, D.82120
> > >     jne .L76    #,
> > > .L137:
> > > 
> > > 
> > > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> > 
> > testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich
> 
> Nadal nie rozumiem jakie korzyści z analizy asemblera będę miał jako 
> programista C++. Kiedyś byle jak napisana procedura w AMS działała 3
> razy szybciej niż porządnie napisana w C i z 5 razy szybciej niż w C++.
> Ale te czasy minęły, teraz trzeba bardzo dużo pracy włożyć aby czasami
> pokonać kompilator o parę procent. Ja raczej bym chciał lepiej wiedzieć 
> jak pisać w C++ aby kompilator generował efektywny kod przy zachowaniu 
> chociaż minimalnej przejrzystości kodu i podatności na rozbudowę. 
> 
jaki korzysci? poprostu odpowiedz na kolegi pytanie dlazego tu jest wolniej a dlaczego szybciej - akurat ta odpowiedz warto sobie sprawdzic a nie jest to wcale duzo roboty 

gdyby ja to pisal sprawdzilbym sobie to mysle w ciagu 20 minut i bym po prostu wiedzial
Re: Optymalizacja kodu
#310041
Author: (fir)
Date: Sat, 28 Dec 2019 10:58
91 lines
8486 bytes
W dniu sobota, 28 grudnia 2019 11:52:58 UTC+1 użytkownik (fir) napisał:
> W dniu sobota, 28 grudnia 2019 11:50:11 UTC+1 użytkownik M.M. napisał:
> > On Saturday, December 28, 2019 at 10:26:57 AM UTC+1, (fir) wrote:
> > > W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > > > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > > > 
> > > > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > > > 
> > > > > > > > > Pozdrawiam
> > > > > > > > 
> > > > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > > > 
> > > > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > > > 
> > > > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > > > 
> > > > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > > > 
> > > > > https://pastebin.com/xriqX0SS
> > > > > 
> > > > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > > > 
> > > > > movabsq	$6364136223846793005
> > > > > 
> > > > > Pozdrawiam
> > > > > 
> > > > > Pozdrawiam
> > > > 
> > > > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > > > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > > > 
> > > > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > > > 
> > > > widac ze np jedna z oimawianych petli jest 
> > > > 
> > > > .L76:
> > > >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> > > >     leal    1(%rax), %edx   #, tmp522
> > > >     testb   $1, %al #, D.82123
> > > >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> > > >     jne .L138   #,
> > > >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> > > >     cmpq    %r14, %rbp  # tmp566, D.82124
> > > >     je  .L139   #,
> > > > .L72:
> > > >     leaq    4(%rbp), %rax   #, tmp555
> > > >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> > > >     movl    0(%rbp), %eax   # *_756,
> > > >     addq    %rax, %r13  # D.82120, sum
> > > >     subq    $1, %r12    #, D.82120
> > > >     jne .L76    #,
> > > > .L137:
> > > > 
> > > > 
> > > > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> > > 
> > > testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich
> > 
> > Nadal nie rozumiem jakie korzyści z analizy asemblera będę miał jako 
> > programista C++. Kiedyś byle jak napisana procedura w AMS działała 3
> > razy szybciej niż porządnie napisana w C i z 5 razy szybciej niż w C++.
> > Ale te czasy minęły, teraz trzeba bardzo dużo pracy włożyć aby czasami
> > pokonać kompilator o parę procent. Ja raczej bym chciał lepiej wiedzieć 
> > jak pisać w C++ aby kompilator generował efektywny kod przy zachowaniu 
> > chociaż minimalnej przejrzystości kodu i podatności na rozbudowę. 
> > 
> jaki korzysci? poprostu odpowiedz na kolegi pytanie dlazego tu jest wolniej a dlaczego szybciej - akurat ta odpowiedz warto sobie sprawdzic a nie jest to wcale duzo roboty 
> 
> gdyby ja to pisal sprawdzilbym sobie to mysle w ciagu 20 minut i bym po prostu wiedzial

co do tego przyspieszania o kilka procent to nie jestem taki pewien, mi samemu nie chce sie grzebac w asmie ale to zalezy od tego jaki wogole jest powod do optymalizacji (gdybym mial to bym zaczal pewnie na pisanie kodow przy pomocy skalarow lub intrinsicow ale ogladal tez kod w asmie)

ogolnie to jak pisalem sam nie robie teraz optymalizacji czyli tutaj bym wzial zwykle rand()%modulo ew napisal sobie w minute druga wersje z cache w postaci tablicy statycznej n elementow gdyby mi naprawde bardziej zalezalo

duzo wiekszym problemem w programowaniu jest dla mnie teraz kreatywnosc a nie optymalizacja - (ale nie neguuje ze warto sie jej nauczyc, warto jej tez uzywac tez nie neguje, tyle ze dla mnie osobiscie to nie jest ten moment)
Re: Optymalizacja kodu
#310042
Author: (fir)
Date: Sat, 28 Dec 2019 11:11
110 lines
9616 bytes
W dniu sobota, 28 grudnia 2019 11:58:53 UTC+1 użytkownik (fir) napisał:
> W dniu sobota, 28 grudnia 2019 11:52:58 UTC+1 użytkownik (fir) napisał:
> > W dniu sobota, 28 grudnia 2019 11:50:11 UTC+1 użytkownik M.M. napisał:
> > > On Saturday, December 28, 2019 at 10:26:57 AM UTC+1, (fir) wrote:
> > > > W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > > > > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > > > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > > > > 
> > > > > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > > > > 
> > > > > > > > > > Pozdrawiam
> > > > > > > > > 
> > > > > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > > > > 
> > > > > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > > > > 
> > > > > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > > > > 
> > > > > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > > > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > > > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > > > > 
> > > > > > https://pastebin.com/xriqX0SS
> > > > > > 
> > > > > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > > > > 
> > > > > > movabsq	$6364136223846793005
> > > > > > 
> > > > > > Pozdrawiam
> > > > > > 
> > > > > > Pozdrawiam
> > > > > 
> > > > > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > > > > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > > > > 
> > > > > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > > > > 
> > > > > widac ze np jedna z oimawianych petli jest 
> > > > > 
> > > > > .L76:
> > > > >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> > > > >     leal    1(%rax), %edx   #, tmp522
> > > > >     testb   $1, %al #, D.82123
> > > > >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> > > > >     jne .L138   #,
> > > > >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> > > > >     cmpq    %r14, %rbp  # tmp566, D.82124
> > > > >     je  .L139   #,
> > > > > .L72:
> > > > >     leaq    4(%rbp), %rax   #, tmp555
> > > > >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> > > > >     movl    0(%rbp), %eax   # *_756,
> > > > >     addq    %rax, %r13  # D.82120, sum
> > > > >     subq    $1, %r12    #, D.82120
> > > > >     jne .L76    #,
> > > > > .L137:
> > > > > 
> > > > > 
> > > > > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> > > > 
> > > > testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich
> > > 
> > > Nadal nie rozumiem jakie korzyści z analizy asemblera będę miał jako 
> > > programista C++. Kiedyś byle jak napisana procedura w AMS działała 3
> > > razy szybciej niż porządnie napisana w C i z 5 razy szybciej niż w C++.
> > > Ale te czasy minęły, teraz trzeba bardzo dużo pracy włożyć aby czasami
> > > pokonać kompilator o parę procent. Ja raczej bym chciał lepiej wiedzieć 
> > > jak pisać w C++ aby kompilator generował efektywny kod przy zachowaniu 
> > > chociaż minimalnej przejrzystości kodu i podatności na rozbudowę. 
> > > 
> > jaki korzysci? poprostu odpowiedz na kolegi pytanie dlazego tu jest wolniej a dlaczego szybciej - akurat ta odpowiedz warto sobie sprawdzic a nie jest to wcale duzo roboty 
> > 
> > gdyby ja to pisal sprawdzilbym sobie to mysle w ciagu 20 minut i bym po prostu wiedzial
> 
> co do tego przyspieszania o kilka procent to nie jestem taki pewien, mi samemu nie chce sie grzebac w asmie ale to zalezy od tego jaki wogole jest powod do optymalizacji (gdybym mial to bym zaczal pewnie na pisanie kodow przy pomocy skalarow lub intrinsicow ale ogladal tez kod w asmie)
> 
> ogolnie to jak pisalem sam nie robie teraz optymalizacji czyli tutaj bym wzial zwykle rand()%modulo ew napisal sobie w minute druga wersje z cache w postaci tablicy statycznej n elementow gdyby mi naprawde bardziej zalezalo
> 
> duzo wiekszym problemem w programowaniu jest dla mnie teraz kreatywnosc a nie optymalizacja - (ale nie neguuje ze warto sie jej nauczyc, warto jej tez uzywac tez nie neguje, tyle ze dla mnie osobiscie to nie jest ten moment)


ew niech kolega napisze ze dwa te testy
w czystym c w postaci jednego pliku c (moge byc bez funkcji miezenia czasu, sam rdzen sprawy


test1() {.. }
test2() {.. }

main()
{
  test1();
  test2();
}

to ew moge zdizasemblowac u siebie (co prawda to chyba bez sensu bo ja ciagle siedze na 32 bitowym xp (z wlasnego wyboru), a moj komp w win10 od lat w drugim pokoju porasta kurzem (i nie che mi sie na nim testowac bo musialbym przynosic odkurzac, przyzwyczajac sie do edytorow i okienek na zimniejszym w odczuciu systemie itd itd)

sama dizasemblacje z kolei lubie spozieranie w asma nie jest zle (dodam ze sam jestem tworca asemblera (org-asm, fajne bajery z tym asmem) sam sie zastanawiam czy nie warto by wrocic i w nim pogrzebac
Re: Optymalizacja kodu
#310043
Author: (fir)
Date: Sat, 28 Dec 2019 11:12
113 lines
10152 bytes
W dniu sobota, 28 grudnia 2019 12:11:16 UTC+1 użytkownik (fir) napisał:
> W dniu sobota, 28 grudnia 2019 11:58:53 UTC+1 użytkownik (fir) napisał:
> > W dniu sobota, 28 grudnia 2019 11:52:58 UTC+1 użytkownik (fir) napisał:
> > > W dniu sobota, 28 grudnia 2019 11:50:11 UTC+1 użytkownik M.M. napisał:
> > > > On Saturday, December 28, 2019 at 10:26:57 AM UTC+1, (fir) wrote:
> > > > > W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > > > > > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > > > > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > > > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > > > > > 
> > > > > > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > > > > > 
> > > > > > > > > > > Pozdrawiam
> > > > > > > > > > 
> > > > > > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > > > > > 
> > > > > > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > > > > > 
> > > > > > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > > > > > 
> > > > > > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > > > > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > > > > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > > > > > 
> > > > > > > https://pastebin.com/xriqX0SS
> > > > > > > 
> > > > > > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > > > > > 
> > > > > > > movabsq	$6364136223846793005
> > > > > > > 
> > > > > > > Pozdrawiam
> > > > > > > 
> > > > > > > Pozdrawiam
> > > > > > 
> > > > > > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > > > > > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > > > > > 
> > > > > > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > > > > > 
> > > > > > widac ze np jedna z oimawianych petli jest 
> > > > > > 
> > > > > > .L76:
> > > > > >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> > > > > >     leal    1(%rax), %edx   #, tmp522
> > > > > >     testb   $1, %al #, D.82123
> > > > > >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> > > > > >     jne .L138   #,
> > > > > >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> > > > > >     cmpq    %r14, %rbp  # tmp566, D.82124
> > > > > >     je  .L139   #,
> > > > > > .L72:
> > > > > >     leaq    4(%rbp), %rax   #, tmp555
> > > > > >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> > > > > >     movl    0(%rbp), %eax   # *_756,
> > > > > >     addq    %rax, %r13  # D.82120, sum
> > > > > >     subq    $1, %r12    #, D.82120
> > > > > >     jne .L76    #,
> > > > > > .L137:
> > > > > > 
> > > > > > 
> > > > > > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> > > > > 
> > > > > testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich
> > > > 
> > > > Nadal nie rozumiem jakie korzyści z analizy asemblera będę miał jako 
> > > > programista C++. Kiedyś byle jak napisana procedura w AMS działała 3
> > > > razy szybciej niż porządnie napisana w C i z 5 razy szybciej niż w C++.
> > > > Ale te czasy minęły, teraz trzeba bardzo dużo pracy włożyć aby czasami
> > > > pokonać kompilator o parę procent. Ja raczej bym chciał lepiej wiedzieć 
> > > > jak pisać w C++ aby kompilator generował efektywny kod przy zachowaniu 
> > > > chociaż minimalnej przejrzystości kodu i podatności na rozbudowę. 
> > > > 
> > > jaki korzysci? poprostu odpowiedz na kolegi pytanie dlazego tu jest wolniej a dlaczego szybciej - akurat ta odpowiedz warto sobie sprawdzic a nie jest to wcale duzo roboty 
> > > 
> > > gdyby ja to pisal sprawdzilbym sobie to mysle w ciagu 20 minut i bym po prostu wiedzial
> > 
> > co do tego przyspieszania o kilka procent to nie jestem taki pewien, mi samemu nie chce sie grzebac w asmie ale to zalezy od tego jaki wogole jest powod do optymalizacji (gdybym mial to bym zaczal pewnie na pisanie kodow przy pomocy skalarow lub intrinsicow ale ogladal tez kod w asmie)
> > 
> > ogolnie to jak pisalem sam nie robie teraz optymalizacji czyli tutaj bym wzial zwykle rand()%modulo ew napisal sobie w minute druga wersje z cache w postaci tablicy statycznej n elementow gdyby mi naprawde bardziej zalezalo
> > 
> > duzo wiekszym problemem w programowaniu jest dla mnie teraz kreatywnosc a nie optymalizacja - (ale nie neguuje ze warto sie jej nauczyc, warto jej tez uzywac tez nie neguje, tyle ze dla mnie osobiscie to nie jest ten moment)
> 
> 
> ew niech kolega napisze ze dwa te testy
> w czystym c w postaci jednego pliku c (moge byc bez funkcji miezenia czasu, sam rdzen sprawy
> 
> 
> test1() {.. }
> test2() {.. }
> 
> main()
> {
>   test1();
>   test2();
> }
> 
> to ew moge zdizasemblowac u siebie (co prawda to chyba bez sensu bo ja ciagle siedze na 32 bitowym xp (z wlasnego wyboru), a moj komp w win10 od lat w drugim pokoju porasta kurzem (i nie che mi sie na nim testowac bo musialbym przynosic odkurzac, przyzwyczajac sie do edytorow i okienek na zimniejszym w odczuciu systemie itd itd)
> 
> sama dizasemblacje z kolei lubie spozieranie w asma nie jest zle (dodam ze sam jestem tworca asemblera (org-asm, fajne bajery z tym asmem) sam sie zastanawiam czy nie warto by wrocic i w nim pogrzebac

aha w sumie to mozna zdizasemblowac online, ale wolalbym by kolega napisal ten kod w wersji c i mozemy zobaczyc
Re: Optymalizacja kodu
#310044
Author: M.M.
Date: Sun, 29 Dec 2019 04:38
121 lines
10648 bytes
On Saturday, December 28, 2019 at 12:12:07 PM UTC+1, (fir) wrote:
> W dniu sobota, 28 grudnia 2019 12:11:16 UTC+1 użytkownik (fir) napisał:
> > W dniu sobota, 28 grudnia 2019 11:58:53 UTC+1 użytkownik (fir) napisał:
> > > W dniu sobota, 28 grudnia 2019 11:52:58 UTC+1 użytkownik (fir) napisał:
> > > > W dniu sobota, 28 grudnia 2019 11:50:11 UTC+1 użytkownik M.M. napisał:
> > > > > On Saturday, December 28, 2019 at 10:26:57 AM UTC+1, (fir) wrote:
> > > > > > W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > > > > > > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > > > > > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > > > > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > > > > > > 
> > > > > > > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > > > > > > 
> > > > > > > > > > > > Pozdrawiam
> > > > > > > > > > > 
> > > > > > > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > > > > > > 
> > > > > > > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > > > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > > > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > > > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > > > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > > > > > > 
> > > > > > > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > > > > > > 
> > > > > > > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > > > > > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > > > > > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > > > > > > 
> > > > > > > > https://pastebin.com/xriqX0SS
> > > > > > > > 
> > > > > > > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > > > > > > 
> > > > > > > > movabsq	$6364136223846793005
> > > > > > > > 
> > > > > > > > Pozdrawiam
> > > > > > > > 
> > > > > > > > Pozdrawiam
> > > > > > > 
> > > > > > > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > > > > > > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > > > > > > 
> > > > > > > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > > > > > > 
> > > > > > > widac ze np jedna z oimawianych petli jest 
> > > > > > > 
> > > > > > > .L76:
> > > > > > >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> > > > > > >     leal    1(%rax), %edx   #, tmp522
> > > > > > >     testb   $1, %al #, D.82123
> > > > > > >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> > > > > > >     jne .L138   #,
> > > > > > >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> > > > > > >     cmpq    %r14, %rbp  # tmp566, D.82124
> > > > > > >     je  .L139   #,
> > > > > > > .L72:
> > > > > > >     leaq    4(%rbp), %rax   #, tmp555
> > > > > > >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> > > > > > >     movl    0(%rbp), %eax   # *_756,
> > > > > > >     addq    %rax, %r13  # D.82120, sum
> > > > > > >     subq    $1, %r12    #, D.82120
> > > > > > >     jne .L76    #,
> > > > > > > .L137:
> > > > > > > 
> > > > > > > 
> > > > > > > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> > > > > > 
> > > > > > testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich
> > > > > 
> > > > > Nadal nie rozumiem jakie korzyści z analizy asemblera będę miał jako 
> > > > > programista C++. Kiedyś byle jak napisana procedura w AMS działała 3
> > > > > razy szybciej niż porządnie napisana w C i z 5 razy szybciej niż w C++.
> > > > > Ale te czasy minęły, teraz trzeba bardzo dużo pracy włożyć aby czasami
> > > > > pokonać kompilator o parę procent. Ja raczej bym chciał lepiej wiedzieć 
> > > > > jak pisać w C++ aby kompilator generował efektywny kod przy zachowaniu 
> > > > > chociaż minimalnej przejrzystości kodu i podatności na rozbudowę. 
> > > > > 
> > > > jaki korzysci? poprostu odpowiedz na kolegi pytanie dlazego tu jest wolniej a dlaczego szybciej - akurat ta odpowiedz warto sobie sprawdzic a nie jest to wcale duzo roboty 
> > > > 
> > > > gdyby ja to pisal sprawdzilbym sobie to mysle w ciagu 20 minut i bym po prostu wiedzial
> > > 
> > > co do tego przyspieszania o kilka procent to nie jestem taki pewien, mi samemu nie chce sie grzebac w asmie ale to zalezy od tego jaki wogole jest powod do optymalizacji (gdybym mial to bym zaczal pewnie na pisanie kodow przy pomocy skalarow lub intrinsicow ale ogladal tez kod w asmie)
> > > 
> > > ogolnie to jak pisalem sam nie robie teraz optymalizacji czyli tutaj bym wzial zwykle rand()%modulo ew napisal sobie w minute druga wersje z cache w postaci tablicy statycznej n elementow gdyby mi naprawde bardziej zalezalo
> > > 
> > > duzo wiekszym problemem w programowaniu jest dla mnie teraz kreatywnosc a nie optymalizacja - (ale nie neguuje ze warto sie jej nauczyc, warto jej tez uzywac tez nie neguje, tyle ze dla mnie osobiscie to nie jest ten moment)
> > 
> > 
> > ew niech kolega napisze ze dwa te testy
> > w czystym c w postaci jednego pliku c (moge byc bez funkcji miezenia czasu, sam rdzen sprawy
> > 
> > 
> > test1() {.. }
> > test2() {.. }
> > 
> > main()
> > {
> >   test1();
> >   test2();
> > }
> > 
> > to ew moge zdizasemblowac u siebie (co prawda to chyba bez sensu bo ja ciagle siedze na 32 bitowym xp (z wlasnego wyboru), a moj komp w win10 od lat w drugim pokoju porasta kurzem (i nie che mi sie na nim testowac bo musialbym przynosic odkurzac, przyzwyczajac sie do edytorow i okienek na zimniejszym w odczuciu systemie itd itd)
> > 
> > sama dizasemblacje z kolei lubie spozieranie w asma nie jest zle (dodam ze sam jestem tworca asemblera (org-asm, fajne bajery z tym asmem) sam sie zastanawiam czy nie warto by wrocic i w nim pogrzebac
> 
> aha w sumie to mozna zdizasemblowac online, ale wolalbym by kolega napisal ten kod w wersji c i mozemy zobaczyc

Przepraszam, ale moim zdaniem zainwestowany czas w naukę asemblera nie
zwróci się. Z 20 lat temu się uczyłem asemblera, w komercyjnym programie
wykorzystałem z może jeden raz w życiu, a autor książki mnie zapewniał, że
osoby które nauczyły się asemblera nie żałują teraz tego :)

Pozdrawiam
Re: Optymalizacja kodu
#310045
Author: (fir)
Date: Sun, 29 Dec 2019 04:50
124 lines
11410 bytes
W dniu niedziela, 29 grudnia 2019 05:38:56 UTC+1 użytkownik M.M. napisał:
> On Saturday, December 28, 2019 at 12:12:07 PM UTC+1, (fir) wrote:
> > W dniu sobota, 28 grudnia 2019 12:11:16 UTC+1 użytkownik (fir) napisał:
> > > W dniu sobota, 28 grudnia 2019 11:58:53 UTC+1 użytkownik (fir) napisał:
> > > > W dniu sobota, 28 grudnia 2019 11:52:58 UTC+1 użytkownik (fir) napisał:
> > > > > W dniu sobota, 28 grudnia 2019 11:50:11 UTC+1 użytkownik M.M. napisał:
> > > > > > On Saturday, December 28, 2019 at 10:26:57 AM UTC+1, (fir) wrote:
> > > > > > > W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > > > > > > > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > > > > > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > > > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > > > > > > > 
> > > > > > > > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > > > > > > > 
> > > > > > > > > > > > > Pozdrawiam
> > > > > > > > > > > > 
> > > > > > > > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > > > > > > > 
> > > > > > > > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > > > > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > > > > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > > > > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > > > > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > > > > > > > 
> > > > > > > > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > > > > > > > 
> > > > > > > > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > > > > > > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > > > > > > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > > > > > > > 
> > > > > > > > > https://pastebin.com/xriqX0SS
> > > > > > > > > 
> > > > > > > > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > > > > > > > 
> > > > > > > > > movabsq	$6364136223846793005
> > > > > > > > > 
> > > > > > > > > Pozdrawiam
> > > > > > > > > 
> > > > > > > > > Pozdrawiam
> > > > > > > > 
> > > > > > > > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > > > > > > > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > > > > > > > 
> > > > > > > > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > > > > > > > 
> > > > > > > > widac ze np jedna z oimawianych petli jest 
> > > > > > > > 
> > > > > > > > .L76:
> > > > > > > >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> > > > > > > >     leal    1(%rax), %edx   #, tmp522
> > > > > > > >     testb   $1, %al #, D.82123
> > > > > > > >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> > > > > > > >     jne .L138   #,
> > > > > > > >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> > > > > > > >     cmpq    %r14, %rbp  # tmp566, D.82124
> > > > > > > >     je  .L139   #,
> > > > > > > > .L72:
> > > > > > > >     leaq    4(%rbp), %rax   #, tmp555
> > > > > > > >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> > > > > > > >     movl    0(%rbp), %eax   # *_756,
> > > > > > > >     addq    %rax, %r13  # D.82120, sum
> > > > > > > >     subq    $1, %r12    #, D.82120
> > > > > > > >     jne .L76    #,
> > > > > > > > .L137:
> > > > > > > > 
> > > > > > > > 
> > > > > > > > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> > > > > > > 
> > > > > > > testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich
> > > > > > 
> > > > > > Nadal nie rozumiem jakie korzyści z analizy asemblera będę miał jako 
> > > > > > programista C++. Kiedyś byle jak napisana procedura w AMS działała 3
> > > > > > razy szybciej niż porządnie napisana w C i z 5 razy szybciej niż w C++.
> > > > > > Ale te czasy minęły, teraz trzeba bardzo dużo pracy włożyć aby czasami
> > > > > > pokonać kompilator o parę procent. Ja raczej bym chciał lepiej wiedzieć 
> > > > > > jak pisać w C++ aby kompilator generował efektywny kod przy zachowaniu 
> > > > > > chociaż minimalnej przejrzystości kodu i podatności na rozbudowę. 
> > > > > > 
> > > > > jaki korzysci? poprostu odpowiedz na kolegi pytanie dlazego tu jest wolniej a dlaczego szybciej - akurat ta odpowiedz warto sobie sprawdzic a nie jest to wcale duzo roboty 
> > > > > 
> > > > > gdyby ja to pisal sprawdzilbym sobie to mysle w ciagu 20 minut i bym po prostu wiedzial
> > > > 
> > > > co do tego przyspieszania o kilka procent to nie jestem taki pewien, mi samemu nie chce sie grzebac w asmie ale to zalezy od tego jaki wogole jest powod do optymalizacji (gdybym mial to bym zaczal pewnie na pisanie kodow przy pomocy skalarow lub intrinsicow ale ogladal tez kod w asmie)
> > > > 
> > > > ogolnie to jak pisalem sam nie robie teraz optymalizacji czyli tutaj bym wzial zwykle rand()%modulo ew napisal sobie w minute druga wersje z cache w postaci tablicy statycznej n elementow gdyby mi naprawde bardziej zalezalo
> > > > 
> > > > duzo wiekszym problemem w programowaniu jest dla mnie teraz kreatywnosc a nie optymalizacja - (ale nie neguuje ze warto sie jej nauczyc, warto jej tez uzywac tez nie neguje, tyle ze dla mnie osobiscie to nie jest ten moment)
> > > 
> > > 
> > > ew niech kolega napisze ze dwa te testy
> > > w czystym c w postaci jednego pliku c (moge byc bez funkcji miezenia czasu, sam rdzen sprawy
> > > 
> > > 
> > > test1() {.. }
> > > test2() {.. }
> > > 
> > > main()
> > > {
> > >   test1();
> > >   test2();
> > > }
> > > 
> > > to ew moge zdizasemblowac u siebie (co prawda to chyba bez sensu bo ja ciagle siedze na 32 bitowym xp (z wlasnego wyboru), a moj komp w win10 od lat w drugim pokoju porasta kurzem (i nie che mi sie na nim testowac bo musialbym przynosic odkurzac, przyzwyczajac sie do edytorow i okienek na zimniejszym w odczuciu systemie itd itd)
> > > 
> > > sama dizasemblacje z kolei lubie spozieranie w asma nie jest zle (dodam ze sam jestem tworca asemblera (org-asm, fajne bajery z tym asmem) sam sie zastanawiam czy nie warto by wrocic i w nim pogrzebac
> > 
> > aha w sumie to mozna zdizasemblowac online, ale wolalbym by kolega napisal ten kod w wersji c i mozemy zobaczyc
> 
> Przepraszam, ale moim zdaniem zainwestowany czas w naukę asemblera nie
> zwróci się. Z 20 lat temu się uczyłem asemblera, w komercyjnym programie
> wykorzystałem z może jeden raz w życiu, a autor książki mnie zapewniał, że
> osoby które nauczyły się asemblera nie żałują teraz tego :)
> 
ja nie zaluje...a czas sie zwroci bo jest to dosyc maly czas bo asm jest dosyc prosty... mozna np wziac moj asembler i w nim sie latwo pisze, latwe wejscie do asma imo (choc nie wklepalem wszystkich kombinacji rejestrow i mnemonikow)

post o asmie wrzucilem chyba ba pl.comp.programming z malym przykladem jak prosto mozna mierzyc dokladnie co do cykla ile trwaja wybrana fragmenty kodu w asmie
Re: Optymalizacja kodu
#310046
Author: M.M.
Date: Sun, 29 Dec 2019 05:36
130 lines
11896 bytes
On Sunday, December 29, 2019 at 5:50:35 AM UTC+1, (fir) wrote:
> W dniu niedziela, 29 grudnia 2019 05:38:56 UTC+1 użytkownik M.M. napisał:
> > On Saturday, December 28, 2019 at 12:12:07 PM UTC+1, (fir) wrote:
> > > W dniu sobota, 28 grudnia 2019 12:11:16 UTC+1 użytkownik (fir) napisał:
> > > > W dniu sobota, 28 grudnia 2019 11:58:53 UTC+1 użytkownik (fir) napisał:
> > > > > W dniu sobota, 28 grudnia 2019 11:52:58 UTC+1 użytkownik (fir) napisał:
> > > > > > W dniu sobota, 28 grudnia 2019 11:50:11 UTC+1 użytkownik M.M. napisał:
> > > > > > > On Saturday, December 28, 2019 at 10:26:57 AM UTC+1, (fir) wrote:
> > > > > > > > W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > > > > > > > > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > > > > > > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > > > > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > > > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > > > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > > > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > > > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > Pozdrawiam
> > > > > > > > > > > > > 
> > > > > > > > > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > > > > > > > > 
> > > > > > > > > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > > > > > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > > > > > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > > > > > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > > > > > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > > > > > > > > 
> > > > > > > > > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > > > > > > > > 
> > > > > > > > > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > > > > > > > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > > > > > > > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > > > > > > > > 
> > > > > > > > > > https://pastebin.com/xriqX0SS
> > > > > > > > > > 
> > > > > > > > > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > > > > > > > > 
> > > > > > > > > > movabsq	$6364136223846793005
> > > > > > > > > > 
> > > > > > > > > > Pozdrawiam
> > > > > > > > > > 
> > > > > > > > > > Pozdrawiam
> > > > > > > > > 
> > > > > > > > > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > > > > > > > > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > > > > > > > > 
> > > > > > > > > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > > > > > > > > 
> > > > > > > > > widac ze np jedna z oimawianych petli jest 
> > > > > > > > > 
> > > > > > > > > .L76:
> > > > > > > > >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> > > > > > > > >     leal    1(%rax), %edx   #, tmp522
> > > > > > > > >     testb   $1, %al #, D.82123
> > > > > > > > >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> > > > > > > > >     jne .L138   #,
> > > > > > > > >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> > > > > > > > >     cmpq    %r14, %rbp  # tmp566, D.82124
> > > > > > > > >     je  .L139   #,
> > > > > > > > > .L72:
> > > > > > > > >     leaq    4(%rbp), %rax   #, tmp555
> > > > > > > > >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> > > > > > > > >     movl    0(%rbp), %eax   # *_756,
> > > > > > > > >     addq    %rax, %r13  # D.82120, sum
> > > > > > > > >     subq    $1, %r12    #, D.82120
> > > > > > > > >     jne .L76    #,
> > > > > > > > > .L137:
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> > > > > > > > 
> > > > > > > > testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich
> > > > > > > 
> > > > > > > Nadal nie rozumiem jakie korzyści z analizy asemblera będę miał jako 
> > > > > > > programista C++. Kiedyś byle jak napisana procedura w AMS działała 3
> > > > > > > razy szybciej niż porządnie napisana w C i z 5 razy szybciej niż w C++.
> > > > > > > Ale te czasy minęły, teraz trzeba bardzo dużo pracy włożyć aby czasami
> > > > > > > pokonać kompilator o parę procent. Ja raczej bym chciał lepiej wiedzieć 
> > > > > > > jak pisać w C++ aby kompilator generował efektywny kod przy zachowaniu 
> > > > > > > chociaż minimalnej przejrzystości kodu i podatności na rozbudowę. 
> > > > > > > 
> > > > > > jaki korzysci? poprostu odpowiedz na kolegi pytanie dlazego tu jest wolniej a dlaczego szybciej - akurat ta odpowiedz warto sobie sprawdzic a nie jest to wcale duzo roboty 
> > > > > > 
> > > > > > gdyby ja to pisal sprawdzilbym sobie to mysle w ciagu 20 minut i bym po prostu wiedzial
> > > > > 
> > > > > co do tego przyspieszania o kilka procent to nie jestem taki pewien, mi samemu nie chce sie grzebac w asmie ale to zalezy od tego jaki wogole jest powod do optymalizacji (gdybym mial to bym zaczal pewnie na pisanie kodow przy pomocy skalarow lub intrinsicow ale ogladal tez kod w asmie)
> > > > > 
> > > > > ogolnie to jak pisalem sam nie robie teraz optymalizacji czyli tutaj bym wzial zwykle rand()%modulo ew napisal sobie w minute druga wersje z cache w postaci tablicy statycznej n elementow gdyby mi naprawde bardziej zalezalo
> > > > > 
> > > > > duzo wiekszym problemem w programowaniu jest dla mnie teraz kreatywnosc a nie optymalizacja - (ale nie neguuje ze warto sie jej nauczyc, warto jej tez uzywac tez nie neguje, tyle ze dla mnie osobiscie to nie jest ten moment)
> > > > 
> > > > 
> > > > ew niech kolega napisze ze dwa te testy
> > > > w czystym c w postaci jednego pliku c (moge byc bez funkcji miezenia czasu, sam rdzen sprawy
> > > > 
> > > > 
> > > > test1() {.. }
> > > > test2() {.. }
> > > > 
> > > > main()
> > > > {
> > > >   test1();
> > > >   test2();
> > > > }
> > > > 
> > > > to ew moge zdizasemblowac u siebie (co prawda to chyba bez sensu bo ja ciagle siedze na 32 bitowym xp (z wlasnego wyboru), a moj komp w win10 od lat w drugim pokoju porasta kurzem (i nie che mi sie na nim testowac bo musialbym przynosic odkurzac, przyzwyczajac sie do edytorow i okienek na zimniejszym w odczuciu systemie itd itd)
> > > > 
> > > > sama dizasemblacje z kolei lubie spozieranie w asma nie jest zle (dodam ze sam jestem tworca asemblera (org-asm, fajne bajery z tym asmem) sam sie zastanawiam czy nie warto by wrocic i w nim pogrzebac
> > > 
> > > aha w sumie to mozna zdizasemblowac online, ale wolalbym by kolega napisal ten kod w wersji c i mozemy zobaczyc
> > 
> > Przepraszam, ale moim zdaniem zainwestowany czas w naukę asemblera nie
> > zwróci się. Z 20 lat temu się uczyłem asemblera, w komercyjnym programie
> > wykorzystałem z może jeden raz w życiu, a autor książki mnie zapewniał, że
> > osoby które nauczyły się asemblera nie żałują teraz tego :)
> > 
> ja nie zaluje...a czas sie zwroci bo jest to dosyc maly czas bo asm jest dosyc prosty... mozna np wziac moj asembler i w nim sie latwo pisze, latwe wejscie do asma imo (choc nie wklepalem wszystkich kombinacji rejestrow i mnemonikow)
> 
> post o asmie wrzucilem chyba ba pl.comp.programming z malym przykladem jak prosto mozna mierzyc dokladnie co do cykla ile trwaja wybrana fragmenty kodu w asmie

Niektórzy nie chcą pisać w C, niektórzy nawet w C++, bo za niskopoziomowy 
język.

Pozdrawiam
Re: Optymalizacja kodu
#310047
Author: (fir)
Date: Sun, 29 Dec 2019 11:20
190 lines
13858 bytes
W dniu niedziela, 29 grudnia 2019 06:36:04 UTC+1 użytkownik M.M. napisał:
> On Sunday, December 29, 2019 at 5:50:35 AM UTC+1, (fir) wrote:
> > W dniu niedziela, 29 grudnia 2019 05:38:56 UTC+1 użytkownik M.M. napisał:
> > > On Saturday, December 28, 2019 at 12:12:07 PM UTC+1, (fir) wrote:
> > > > W dniu sobota, 28 grudnia 2019 12:11:16 UTC+1 użytkownik (fir) napisał:
> > > > > W dniu sobota, 28 grudnia 2019 11:58:53 UTC+1 użytkownik (fir) napisał:
> > > > > > W dniu sobota, 28 grudnia 2019 11:52:58 UTC+1 użytkownik (fir) napisał:
> > > > > > > W dniu sobota, 28 grudnia 2019 11:50:11 UTC+1 użytkownik M.M. napisał:
> > > > > > > > On Saturday, December 28, 2019 at 10:26:57 AM UTC+1, (fir) wrote:
> > > > > > > > > W dniu sobota, 28 grudnia 2019 10:11:26 UTC+1 użytkownik (fir) napisał:
> > > > > > > > > > W dniu sobota, 28 grudnia 2019 03:44:41 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > > On Friday, December 27, 2019 at 10:01:25 PM UTC+1, (fir) wrote:
> > > > > > > > > > > > W dniu piątek, 27 grudnia 2019 21:54:14 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > > > > On Friday, December 27, 2019 at 8:18:46 PM UTC+1, (fir) wrote:
> > > > > > > > > > > > > > W dniu piątek, 27 grudnia 2019 20:12:09 UTC+1 użytkownik M.M. napisał:
> > > > > > > > > > > > > > > On Friday, December 27, 2019 at 7:48:22 PM UTC+1, (fir) wrote:
> > > > > > > > > > > > > > > > a co z dezasemblacja? to calkiem proste a wiele by wyjasnilo
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > Jest kilka problemów z tym. Nie znam zasad łączenia instrukcji w pary/trójki 
> > > > > > > > > > > > > > > żeby procesor mógł je wykonać równocześnie, o czasach wykonania nie wspomnę.
> > > > > > > > > > > > > > > No i bym musiał procedurę zostawić w asemblerze, dopracować ją (czytaj: napisać
> > > > > > > > > > > > > > > lepiej niż kompilator) i utrzymywać w asemblerze. Wiec nawet jak znajdę
> > > > > > > > > > > > > > > wyjaśnienie, to chyba nic mi z tego.
> > > > > > > > > > > > > > > 
> > > > > > > > > > > > > > > Pozdrawiam
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > chodzi o dezasemblacje i zobazenie co sie zmienilo miedzy ta wolniejsza a szybsza wersje a nie o pisanie asma (ktore nie jest zreszta wcale takie trudne mysle ze idzie sie nauczyc w dzien (choc sam nie pisalme jeszcze 64 bitowego asma)
> > > > > > > > > > > > > 
> > > > > > > > > > > > > Zgodzę się, że dla kogoś kto biegle zna i używa asemblera na 386, byłby to
> > > > > > > > > > > > > dobry przykład jak należy, a jak nie należy pisać wydajny kod w asemblerze.
> > > > > > > > > > > > > Ja piszę w C++, dla mnie wstawka jednej instrukcji w asemblerze (np. to
> > > > > > > > > > > > > popcount, xchange, rot) maksymalne użycie asemblera. Taki ktoś jak ja 
> > > > > > > > > > > > > chyba nie wyniesie z tego żadnej nauki?
> > > > > > > > > > > > > 
> > > > > > > > > > > > jak to nie - zdezasembluj a dostaniesz odpowiedz na swoje pytaie czemu jest szybciej..jak nie umiesz czytac asma to zapostuj go na grupie tylko trzeba by zdizasemblowac odpowiednie kawalki
> > > > > > > > > > > 
> > > > > > > > > > > Nie chciałem powiedzieć, że nie można się dowiedzieć z asemblera, tylko że jak
> > > > > > > > > > > się dowiem, to nie spożytkuję tej wiedzy w innych programach. Ale nie ma
> > > > > > > > > > > problemu, to tylko dodanie opcji -S do kompilatora:
> > > > > > > > > > > 
> > > > > > > > > > > https://pastebin.com/xriqX0SS
> > > > > > > > > > > 
> > > > > > > > > > > Które to kawałki - trudno powiedzieć. Może testy oddziela instrukcja:
> > > > > > > > > > > 
> > > > > > > > > > > movabsq	$6364136223846793005
> > > > > > > > > > > 
> > > > > > > > > > > Pozdrawiam
> > > > > > > > > > > 
> > > > > > > > > > > Pozdrawiam
> > > > > > > > > > 
> > > > > > > > > > potrzebujesz napisac test w minimalnej wersji w c (tak zeby nie nylo niepotrzebnych wywolan) po czym zdizasemblowac wlasnie ten kawalek
> > > > > > > > > > (najlepiej w tej normalnej skladni a nie w tej i z komentarzami)
> > > > > > > > > > 
> > > > > > > > > > tutaj ja bym znalazl latwo te kawalki ale nie je pisalem bazowy kod i nie mam go w pamieci (zwlaszcza ze jest napisany w durnym dla mnie c++) po co tu sa wywolywane te wywolania do marsenne twister mialo chodzic o oryginalny kod z loopami, ciezko mi zmapowac to na kod w c ktorego nie znam, choc generalnie widac ze jest jak kawa na lawe - jako ze pokazuje nazwy funkcji ktore wola wywolaj sobie cos o uniklanej nazwie na poczatklu i koncu kawalka i znajdz przec control+f w teksiecie
> > > > > > > > > > 
> > > > > > > > > > widac ze np jedna z oimawianych petli jest 
> > > > > > > > > > 
> > > > > > > > > > .L76:
> > > > > > > > > >     movl    28832(%rsp), %eax   # rndBuf.select, D.82123
> > > > > > > > > >     leal    1(%rax), %edx   #, tmp522
> > > > > > > > > >     testb   $1, %al #, D.82123
> > > > > > > > > >     movl    %edx, 28832(%rsp)   # tmp522, rndBuf.select
> > > > > > > > > >     jne .L138   #,
> > > > > > > > > >     movq    28824(%rsp), %rbp   # rndBuf.i2, D.82124
> > > > > > > > > >     cmpq    %r14, %rbp  # tmp566, D.82124
> > > > > > > > > >     je  .L139   #,
> > > > > > > > > > .L72:
> > > > > > > > > >     leaq    4(%rbp), %rax   #, tmp555
> > > > > > > > > >     movq    %rax, 28824(%rsp)   # tmp555, rndBuf.i2
> > > > > > > > > >     movl    0(%rbp), %eax   # *_756,
> > > > > > > > > >     addq    %rax, %r13  # D.82120, sum
> > > > > > > > > >     subq    $1, %r12    #, D.82120
> > > > > > > > > >     jne .L76    #,
> > > > > > > > > > .L137:
> > > > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > > ale nei wiem dokladnie ktory to kawalek jak mowie trzeba to zdizasemblowac kawalkami i najlepiej napisac to w c wtedy widac co i jaki nie ma tez w tym nic trudnego tyle ze mi nieprzyjemnie jest debugowac czyjs kod na ktory nie moge patrzec bo jest w c++ i nie mam ogarniete jak on w calosci wyglaa
> > > > > > > > > 
> > > > > > > > > testowanie i optymalizowanie wymaga duzo przepisywania tak ze mysle ze kolega powinien byc gotow na rozbicie tych 5-ciu czy tam ile testow na 5 minimalnych kilkolinijkowcow w c i zdezasemblowanie ich
> > > > > > > > 
> > > > > > > > Nadal nie rozumiem jakie korzyści z analizy asemblera będę miał jako 
> > > > > > > > programista C++. Kiedyś byle jak napisana procedura w AMS działała 3
> > > > > > > > razy szybciej niż porządnie napisana w C i z 5 razy szybciej niż w C++.
> > > > > > > > Ale te czasy minęły, teraz trzeba bardzo dużo pracy włożyć aby czasami
> > > > > > > > pokonać kompilator o parę procent. Ja raczej bym chciał lepiej wiedzieć 
> > > > > > > > jak pisać w C++ aby kompilator generował efektywny kod przy zachowaniu 
> > > > > > > > chociaż minimalnej przejrzystości kodu i podatności na rozbudowę. 
> > > > > > > > 
> > > > > > > jaki korzysci? poprostu odpowiedz na kolegi pytanie dlazego tu jest wolniej a dlaczego szybciej - akurat ta odpowiedz warto sobie sprawdzic a nie jest to wcale duzo roboty 
> > > > > > > 
> > > > > > > gdyby ja to pisal sprawdzilbym sobie to mysle w ciagu 20 minut i bym po prostu wiedzial
> > > > > > 
> > > > > > co do tego przyspieszania o kilka procent to nie jestem taki pewien, mi samemu nie chce sie grzebac w asmie ale to zalezy od tego jaki wogole jest powod do optymalizacji (gdybym mial to bym zaczal pewnie na pisanie kodow przy pomocy skalarow lub intrinsicow ale ogladal tez kod w asmie)
> > > > > > 
> > > > > > ogolnie to jak pisalem sam nie robie teraz optymalizacji czyli tutaj bym wzial zwykle rand()%modulo ew napisal sobie w minute druga wersje z cache w postaci tablicy statycznej n elementow gdyby mi naprawde bardziej zalezalo
> > > > > > 
> > > > > > duzo wiekszym problemem w programowaniu jest dla mnie teraz kreatywnosc a nie optymalizacja - (ale nie neguuje ze warto sie jej nauczyc, warto jej tez uzywac tez nie neguje, tyle ze dla mnie osobiscie to nie jest ten moment)
> > > > > 
> > > > > 
> > > > > ew niech kolega napisze ze dwa te testy
> > > > > w czystym c w postaci jednego pliku c (moge byc bez funkcji miezenia czasu, sam rdzen sprawy
> > > > > 
> > > > > 
> > > > > test1() {.. }
> > > > > test2() {.. }
> > > > > 
> > > > > main()
> > > > > {
> > > > >   test1();
> > > > >   test2();
> > > > > }
> > > > > 
> > > > > to ew moge zdizasemblowac u siebie (co prawda to chyba bez sensu bo ja ciagle siedze na 32 bitowym xp (z wlasnego wyboru), a moj komp w win10 od lat w drugim pokoju porasta kurzem (i nie che mi sie na nim testowac bo musialbym przynosic odkurzac, przyzwyczajac sie do edytorow i okienek na zimniejszym w odczuciu systemie itd itd)
> > > > > 
> > > > > sama dizasemblacje z kolei lubie spozieranie w asma nie jest zle (dodam ze sam jestem tworca asemblera (org-asm, fajne bajery z tym asmem) sam sie zastanawiam czy nie warto by wrocic i w nim pogrzebac
> > > > 
> > > > aha w sumie to mozna zdizasemblowac online, ale wolalbym by kolega napisal ten kod w wersji c i mozemy zobaczyc
> > > 
> > > Przepraszam, ale moim zdaniem zainwestowany czas w naukę asemblera nie
> > > zwróci się. Z 20 lat temu się uczyłem asemblera, w komercyjnym programie
> > > wykorzystałem z może jeden raz w życiu, a autor książki mnie zapewniał, że
> > > osoby które nauczyły się asemblera nie żałują teraz tego :)
> > > 
> > ja nie zaluje...a czas sie zwroci bo jest to dosyc maly czas bo asm jest dosyc prosty... mozna np wziac moj asembler i w nim sie latwo pisze, latwe wejscie do asma imo (choc nie wklepalem wszystkich kombinacji rejestrow i mnemonikow)
> > 
> > post o asmie wrzucilem chyba ba pl.comp.programming z malym przykladem jak prosto mozna mierzyc dokladnie co do cykla ile trwaja wybrana fragmenty kodu w asmie
> 
> Niektórzy nie chcą pisać w C, niektórzy nawet w C++, bo za niskopoziomowy 
> język.
> 
to nie chodzi o pisanie w asmie a o sporadyczne bawienie sie w asmie by wiedziec jak cos doklednie dziala
(nie tylko ile cykli ma jaka komenda ale i kilka innych ciekawych rzeczy (ktore nie ogarniete moga powodowac godziny dni tygodnie i miesiace meki z poziomu c/c+) pojawia sie jak kawa na lawe)

polecam sie pobawic moim asmem bo sporo rzeczy moze sie wyjasnic,

 ja np dopiero ostatnio dowiedzialem sie jak przekazywane są float do printfa

tj jak zrobic

printf(" f = %f ",  123.456);

z poziomu asemblera

wie ktos ? ;c

s

p


o


i

l


y

trzeba cos w tym stylu

  @ f: double(123.456)
 //zapisz double wartosci 123.456 
// (8 bajtow) w sekcji data pod labelem f
// (moja skladnia do tego jest mzoe 
// troceh dziwna pozniej poprawie

   @ txt: " f = %f " 0
// zapisz string w sekcji data pod 
// labelem txt

  mov eax f
   add eax 4
   push (eax)
  mov eax f
   push (eax)
  push txt
    call msvcrt.printf
  pop eax
  pop eax
  pop eax

w asmie widac wszystko jak kawa na lawe 
tutaj w szczegolnosci ze floaty przekazuje sie do printfa jako double przez stos przez wartosc i to w takiej odwroconej kolejnosci (przynajmniej odwroconej wzgledem czegostam ;c)

asm zmusza kodera w c/c++ do nauczenia sie wszystkich waznych rzeczy i t zmusza go do nauczenia sie tego w kilka pierwszych dni i to nauczenia sie latwo


(dlatego polecam jeszze raz moj asm, nie kelepalem w nim jeszcze troche rzeczy ale jak ktos napisze na grupic o mu nie dziala to odpowiem i ew dokoduje te dorobne łatki)
Re: Optymalizacja kodu
#310049
Author: Wojciech Muła
Date: Sun, 29 Dec 2019 19:00
14 lines
2078 bytes
On Friday, December 27, 2019 at 8:45:01 AM UTC+1, M.M. wrote:
> On Thursday, December 26, 2019 at 9:57:09 AM UTC+1, Wojciech Muła wrote:
> > Sprawdź, jak się sprawuje ten algorytm https://lemire.me/blog/2019/07/03/a-fast-16-bit-random-number-generator/
> 
> Mam pytanie, czy można mieć kod tego generatora w swoich programach? Jest
> jakaś licencja?

https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/README.md

"Unless otherwise stated, I make no copyright claim on this code: you may consider it to be in the public domain.

Don't bother forking this code: just steal it."

w.
Re: Optymalizacja kodu
#310050
Author: M.M.
Date: Wed, 01 Jan 2020 16:27
44 lines
3476 bytes
On Sunday, December 29, 2019 at 8:00:28 PM UTC+1, Wojciech Muła wrote:
> On Friday, December 27, 2019 at 8:45:01 AM UTC+1, M.M. wrote:
> > On Thursday, December 26, 2019 at 9:57:09 AM UTC+1, Wojciech Muła wrote:
> > > Sprawdź, jak się sprawuje ten algorytm https://lemire.me/blog/2019/07/03/a-fast-16-bit-random-number-generator/
> > 
> > Mam pytanie, czy można mieć kod tego generatora w swoich programach? Jest
> > jakaś licencja?
> 
> https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/README.md
> 
> "Unless otherwise stated, I make no copyright claim on this code: you may consider it to be in the public domain.
> 
> Don't bother forking this code: just steal it."
> 
> w.

Dzięki za informacje.

Z kilku kolejnych ale nadal pobieżnych testów wynika to samo 
co poprzednio: Można łatwo napisać bardzo wydajną implementację
tego generatora i przechodzi krótkie testy dla wybranych zarodków.
Na średnie testy czeka którąś dobę w kolejce. Jak przejdzie średnie
testy, to zrobię bardzo długie testy, generator wydaje się godny
zainteresowania.

Nie googlałem za teorią do tego generatora. Na pierwszy rzut oka
widać, że stan generatora bazuje na dodawaniu

stan += value;

Więc jak value jest dobrze dobrane, to okres generatora będzie 
równy 2^64 przy stanie na liczbie 64 bitowej. Losowość liczb
podawanych przez generator zależy od funkcji hash na którą są
podawane kolejne wartości. Podobne funkcje hash dla liczb całkowitych
bez znaku można znaleźć na stacku. Widziałem też gdzieś algorytm
genetyczny do generowania takich funkcji, niestety jak działał w 
szczegółach to nie mam bladego pojęcia. 

Zastanawiam się czy ten generator by nie był źródłem gorszych wyników
jakby obliczenia trwały całe lata na wielu maszynach, albo wręcz na
wielu kartach graficznych. Na moim przestarzałym laptopie wygenerowanie
16 miliardów liczb tym generatorem w jednym wątku trwa zaledwie 20 sekund.

Pozdrawiam
Re: Optymalizacja kodu
#310051
Author: M.M.
Date: Thu, 02 Jan 2020 05:14
354 lines
19788 bytes
On Sunday, December 29, 2019 at 8:00:28 PM UTC+1, Wojciech Muła wrote:
> On Friday, December 27, 2019 at 8:45:01 AM UTC+1, M.M. wrote:
> > On Thursday, December 26, 2019 at 9:57:09 AM UTC+1, Wojciech Muła wrote:
> > > Sprawdź, jak się sprawuje ten algorytm https://lemire.me/blog/2019/07/03/a-fast-16-bit-random-number-generator/
> > 
> > Mam pytanie, czy można mieć kod tego generatora w swoich programach? Jest
> > jakaś licencja?
> 
> https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/README.md
> 
> "Unless otherwise stated, I make no copyright claim on this code: you may consider it to be in the public domain.
> 
> Don't bother forking this code: just steal it."
> 
> w.

Uwaga: Czasy są poglądowe, bo komputer był obciążony. Zarodki są inne niż
wyświetlone.


Tutaj pełen test generatora wyhash64 na dieharderze, widać że zaliczony:

time ./MRndCPP2 | dieharder -g200 -a -k2
#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
   rng_name    |rands/second|   Seed   |
stdin_input_raw|  2.24e+07  |2577951266|
#=============================================================================#
        test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
   diehard_birthdays|   0|       100|     100|0.81026922|  PASSED  
      diehard_operm5|   0|   1000000|     100|0.98679548|  PASSED  
  diehard_rank_32x32|   0|     40000|     100|0.71416552|  PASSED  
    diehard_rank_6x8|   0|    100000|     100|0.51696514|  PASSED  
   diehard_bitstream|   0|   2097152|     100|0.63316532|  PASSED  
        diehard_opso|   0|   2097152|     100|0.96492817|  PASSED  
        diehard_oqso|   0|   2097152|     100|0.83902928|  PASSED  
         diehard_dna|   0|   2097152|     100|0.25207588|  PASSED  
diehard_count_1s_str|   0|    256000|     100|0.52915716|  PASSED  
diehard_count_1s_byt|   0|    256000|     100|0.95076645|  PASSED  
 diehard_parking_lot|   0|     12000|     100|0.90388634|  PASSED  
    diehard_2dsphere|   2|      8000|     100|0.28100768|  PASSED  
    diehard_3dsphere|   3|      4000|     100|0.88633340|  PASSED  
     diehard_squeeze|   0|    100000|     100|0.26057188|  PASSED  
        diehard_sums|   0|       100|     100|0.09292146|  PASSED  
        diehard_runs|   0|    100000|     100|0.43772796|  PASSED                                                                                                                               
        diehard_runs|   0|    100000|     100|0.02237980|  PASSED                                                                                                                               
       diehard_craps|   0|    200000|     100|0.69281661|  PASSED                                                                                                                               
       diehard_craps|   0|    200000|     100|0.56674609|  PASSED                                                                                                                               
 marsaglia_tsang_gcd|   0|  10000000|     100|0.23008321|  PASSED                                                                                                                               
 marsaglia_tsang_gcd|   0|  10000000|     100|0.87485793|  PASSED                                                                                                                               
         sts_monobit|   1|    100000|     100|0.33312220|  PASSED                                                                                                                               
            sts_runs|   2|    100000|     100|0.93844784|  PASSED                                                                                                                               
          sts_serial|   1|    100000|     100|0.20273716|  PASSED                                                                                                                               
          sts_serial|   2|    100000|     100|0.09850698|  PASSED                                                                                                                               
          sts_serial|   3|    100000|     100|0.75334509|  PASSED                                                                                                                               
          sts_serial|   3|    100000|     100|0.57132578|  PASSED                                                                                                                               
          sts_serial|   4|    100000|     100|0.99728968|   WEAK                                                                                                                                
          sts_serial|   4|    100000|     100|0.86993019|  PASSED  
          sts_serial|   5|    100000|     100|0.69177051|  PASSED  
          sts_serial|   5|    100000|     100|0.88240774|  PASSED  
          sts_serial|   6|    100000|     100|0.68852405|  PASSED  
          sts_serial|   6|    100000|     100|0.11358621|  PASSED  
          sts_serial|   7|    100000|     100|0.99123468|  PASSED  
          sts_serial|   7|    100000|     100|0.07363269|  PASSED  
          sts_serial|   8|    100000|     100|0.77877807|  PASSED  
          sts_serial|   8|    100000|     100|0.48870919|  PASSED  
          sts_serial|   9|    100000|     100|0.28300283|  PASSED  
          sts_serial|   9|    100000|     100|0.56293370|  PASSED  
          sts_serial|  10|    100000|     100|0.69074909|  PASSED  
          sts_serial|  10|    100000|     100|0.73542549|  PASSED  
          sts_serial|  11|    100000|     100|0.07321933|  PASSED  
          sts_serial|  11|    100000|     100|0.58896333|  PASSED  
          sts_serial|  12|    100000|     100|0.28161926|  PASSED  
          sts_serial|  12|    100000|     100|0.92644298|  PASSED  
          sts_serial|  13|    100000|     100|0.05086176|  PASSED  
          sts_serial|  13|    100000|     100|0.27981417|  PASSED  
          sts_serial|  14|    100000|     100|0.22519486|  PASSED  
          sts_serial|  14|    100000|     100|0.77315819|  PASSED  
          sts_serial|  15|    100000|     100|0.01165574|  PASSED  
          sts_serial|  15|    100000|     100|0.02665459|  PASSED  
          sts_serial|  16|    100000|     100|0.26242221|  PASSED  
          sts_serial|  16|    100000|     100|0.43830761|  PASSED  
         rgb_bitdist|   1|    100000|     100|0.31452766|  PASSED  
         rgb_bitdist|   2|    100000|     100|0.39767941|  PASSED  
         rgb_bitdist|   3|    100000|     100|0.82520370|  PASSED  
         rgb_bitdist|   4|    100000|     100|0.69802529|  PASSED  
         rgb_bitdist|   5|    100000|     100|0.60286533|  PASSED  
         rgb_bitdist|   6|    100000|     100|0.76287425|  PASSED  
         rgb_bitdist|   7|    100000|     100|0.48130619|  PASSED  
         rgb_bitdist|   8|    100000|     100|0.67608036|  PASSED  
         rgb_bitdist|   9|    100000|     100|0.78947721|  PASSED  
         rgb_bitdist|  10|    100000|     100|0.16690659|  PASSED  
         rgb_bitdist|  11|    100000|     100|0.08735874|  PASSED  
         rgb_bitdist|  12|    100000|     100|0.25206410|  PASSED  
rgb_minimum_distance|   2|     10000|    1000|0.00146107|   WEAK   
rgb_minimum_distance|   3|     10000|    1000|0.98873968|  PASSED  
rgb_minimum_distance|   4|     10000|    1000|0.95856433|  PASSED  
rgb_minimum_distance|   5|     10000|    1000|0.80685775|  PASSED  
    rgb_permutations|   2|    100000|     100|0.20047125|  PASSED  
    rgb_permutations|   3|    100000|     100|0.66596447|  PASSED  
    rgb_permutations|   4|    100000|     100|0.50658066|  PASSED  
    rgb_permutations|   5|    100000|     100|0.72548917|  PASSED  
      rgb_lagged_sum|   0|   1000000|     100|0.86970338|  PASSED  
      rgb_lagged_sum|   1|   1000000|     100|0.22662204|  PASSED  
      rgb_lagged_sum|   2|   1000000|     100|0.27081183|  PASSED  
      rgb_lagged_sum|   3|   1000000|     100|0.40143564|  PASSED  
      rgb_lagged_sum|   4|   1000000|     100|0.92310721|  PASSED  
      rgb_lagged_sum|   5|   1000000|     100|0.22827856|  PASSED  
      rgb_lagged_sum|   6|   1000000|     100|0.56825732|  PASSED  
      rgb_lagged_sum|   7|   1000000|     100|0.56570034|  PASSED  
      rgb_lagged_sum|   8|   1000000|     100|0.51714557|  PASSED  
      rgb_lagged_sum|   9|   1000000|     100|0.98392710|  PASSED  
      rgb_lagged_sum|  10|   1000000|     100|0.27250657|  PASSED  
      rgb_lagged_sum|  11|   1000000|     100|0.95516885|  PASSED  
      rgb_lagged_sum|  12|   1000000|     100|0.58962187|  PASSED  
      rgb_lagged_sum|  13|   1000000|     100|0.23946733|  PASSED  
      rgb_lagged_sum|  14|   1000000|     100|0.17323052|  PASSED  
      rgb_lagged_sum|  15|   1000000|     100|0.21578945|  PASSED  
      rgb_lagged_sum|  16|   1000000|     100|0.22688738|  PASSED  
      rgb_lagged_sum|  17|   1000000|     100|0.26143583|  PASSED  
      rgb_lagged_sum|  18|   1000000|     100|0.51841646|  PASSED  
      rgb_lagged_sum|  19|   1000000|     100|0.94883960|  PASSED  
      rgb_lagged_sum|  20|   1000000|     100|0.80882001|  PASSED  
      rgb_lagged_sum|  21|   1000000|     100|0.94493061|  PASSED  
      rgb_lagged_sum|  22|   1000000|     100|0.82077584|  PASSED  
      rgb_lagged_sum|  23|   1000000|     100|0.45537077|  PASSED  
      rgb_lagged_sum|  24|   1000000|     100|0.87466395|  PASSED  
      rgb_lagged_sum|  25|   1000000|     100|0.83690335|  PASSED  
      rgb_lagged_sum|  26|   1000000|     100|0.26485784|  PASSED  
      rgb_lagged_sum|  27|   1000000|     100|0.96001824|  PASSED  
      rgb_lagged_sum|  28|   1000000|     100|0.12250941|  PASSED  
      rgb_lagged_sum|  29|   1000000|     100|0.36885207|  PASSED  
      rgb_lagged_sum|  30|   1000000|     100|0.91444238|  PASSED  
      rgb_lagged_sum|  31|   1000000|     100|0.87605244|  PASSED  
      rgb_lagged_sum|  32|   1000000|     100|0.52384561|  PASSED  
     rgb_kstest_test|   0|     10000|    1000|0.56713236|  PASSED  
     dab_bytedistrib|   0|  51200000|       1|0.69832879|  PASSED  
             dab_dct| 256|     50000|       1|0.83845186|  PASSED  
Preparing to run test 207.  ntuple = 0
        dab_filltree|  32|  15000000|       1|0.47593522|  PASSED  
        dab_filltree|  32|  15000000|       1|0.10222342|  PASSED  
Preparing to run test 208.  ntuple = 0
       dab_filltree2|   0|   5000000|       1|0.10419158|  PASSED  
       dab_filltree2|   1|   5000000|       1|0.21159375|  PASSED  
Preparing to run test 209.  ntuple = 0
        dab_monobit2|  12|  65000000|       1|0.83878560|  PASSED  

real    58m32.504s
user    58m19.365s
sys     5m29.716s


Tuta około 2tys testów w programem pract_rand, widać że dwa rozkłady 
wypadły jako bardzo rzadkie (prawdopodobieństwo około kilku stu-tysięcznych),
pract_rand oznaczył te testy jako średnio podejrzane:

time ./MRndCPP | ../../PractRand/RNG_test stdin
RNG_test using PractRand version 0.93
RNG = RNG_stdin, seed = 0xad8296e3
test set = normal, folding = standard(unknown format)

rng=RNG_stdin, seed=0xad8296e3
length= 128 megabytes (2^27 bytes), time= 2.6 seconds
  no anomalies in 151 test result(s)

rng=RNG_stdin, seed=0xad8296e3
length= 256 megabytes (2^28 bytes), time= 5.8 seconds
  Test Name                         Raw       Processed     Evaluation
  [Low1/8]BCFN(2+1,13-4,T)          R=  +8.4  p =  1.3e-3   unusual          
  ...and 161 test result(s) without anomalies

rng=RNG_stdin, seed=0xad8296e3
length= 512 megabytes (2^29 bytes), time= 11.3 seconds
  no anomalies in 171 test result(s)

rng=RNG_stdin, seed=0xad8296e3
length= 1 gigabyte (2^30 bytes), time= 21.8 seconds
  Test Name                         Raw       Processed     Evaluation
  BCFN(2+1,13-1,T)                  R=  -9.8  p =1-2.1e-5   mildly suspicious
  ...and 182 test result(s) without anomalies

rng=RNG_stdin, seed=0xad8296e3
length= 2 gigabytes (2^31 bytes), time= 41.9 seconds
  Test Name                         Raw       Processed     Evaluation
  BCFN(2+1,13-0,T)                  R=  -9.5  p =1-4.6e-5   mildly suspicious
  ...and 193 test result(s) without anomalies

rng=RNG_stdin, seed=0xad8296e3
length= 4 gigabytes (2^32 bytes), time= 80.4 seconds
  no anomalies in 203 test result(s)

rng=RNG_stdin, seed=0xad8296e3
length= 8 gigabytes (2^33 bytes), time= 159 seconds
  no anomalies in 215 test result(s)

rng=RNG_stdin, seed=0xad8296e3
length= 16 gigabytes (2^34 bytes), time= 314 seconds
  no anomalies in 226 test result(s)

rng=RNG_stdin, seed=0xad8296e3
length= 32 gigabytes (2^35 bytes), time= 621 seconds
  no anomalies in 235 test result(s)

^C

real 19m50.004s
user 19m19.332s
sys 0m38.718s


Tutaj dłuży test programem pract_rand: Jeden test mało 
prawdopodobny 1-8.7e-5, ale pract_rand oznaczył go tylko 
jako unusual.

time ./MRndCPP2 | ../../PractRand/RNG_test stdin
RNG_test using PractRand version 0.93
RNG = RNG_stdin, seed = 0xdbda558d
test set = normal, folding = standard(unknown format)

rng=RNG_stdin, seed=0xdbda558d
length= 128 megabytes (2^27 bytes), time= 2.5 seconds
  no anomalies in 151 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 256 megabytes (2^28 bytes), time= 5.8 seconds
  no anomalies in 162 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 512 megabytes (2^29 bytes), time= 11.4 seconds
  Test Name                         Raw       Processed     Evaluation
  [Low1/8]FPF-14+6/16:cross         R=  +4.4  p =  3.9e-4   unusual          
  ...and 170 test result(s) without anomalies

rng=RNG_stdin, seed=0xdbda558d
length= 1 gigabyte (2^30 bytes), time= 23.5 seconds
  no anomalies in 183 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 2 gigabytes (2^31 bytes), time= 45.1 seconds
  no anomalies in 194 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 4 gigabytes (2^32 bytes), time= 88.9 seconds
  no anomalies in 203 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 8 gigabytes (2^33 bytes), time= 178 seconds
  no anomalies in 215 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 16 gigabytes (2^34 bytes), time= 355 seconds
  no anomalies in 226 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 32 gigabytes (2^35 bytes), time= 762 seconds
  Test Name                         Raw       Processed     Evaluation
  [Low4/32]Gap-16:B                 R=  -4.2  p =1-1.7e-3   unusual          
  ...and 234 test result(s) without anomalies

yyuyrng=RNG_stdin, seed=0xdbda558d
length= 64 gigabytes (2^36 bytes), time= 1759 seconds
  no anomalies in 247 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 128 gigabytes (2^37 bytes), time= 3845 seconds
  Test Name                         Raw       Processed     Evaluation
  BCFN(2+4,13-0,T)                  R=  -9.0  p =1-8.7e-5   unusual          
  ...and 257 test result(s) without anomalies

rng=RNG_stdin, seed=0xdbda558d
length= 256 gigabytes (2^38 bytes), time= 6752 seconds
  no anomalies in 267 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 512 gigabytes (2^39 bytes), time= 12607 seconds
  no anomalies in 279 test result(s)

rng=RNG_stdin, seed=0xdbda558d
length= 1 terabyte (2^40 bytes), time= 24343 seconds
  no anomalies in 290 test result(s)



Poniżej test mojej lekkiej modyfikacji generatora wyhash64, widać
że tylko jeden test ma prawdopodobieństwo 3.0e-3, co na 1-2tys
testów właśnie raz powinno się zdarzyć. Niestety moja modyfikacja
jest wielokrotnie wolniejsza od oryginału, cały program generujący
liczby jest 4 razy wolniejszy:


./MRndCPP | ../../PractRand/RNG_test stdin
RNG_test using PractRand version 0.93
RNG = RNG_stdin, seed = 0xff13eeed
test set = normal, folding = standard(unknown format)

rng=RNG_stdin, seed=0xff13eeed
length= 128 megabytes (2^27 bytes), time= 2.9 seconds
  no anomalies in 151 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 256 megabytes (2^28 bytes), time= 6.7 seconds
  no anomalies in 162 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 512 megabytes (2^29 bytes), time= 13.1 seconds
  no anomalies in 171 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 1 gigabyte (2^30 bytes), time= 25.3 seconds
  no anomalies in 183 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 2 gigabytes (2^31 bytes), time= 48.8 seconds
  no anomalies in 194 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 4 gigabytes (2^32 bytes), time= 94.4 seconds
  Test Name                         Raw       Processed     Evaluation
  [Low4/32]DC6-9x1Bytes-1           R=  +5.9  p =  3.0e-3   unusual          
  ...and 202 test result(s) without anomalies

rng=RNG_stdin, seed=0xff13eeed
length= 8 gigabytes (2^33 bytes), time= 187 seconds
  no anomalies in 215 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 16 gigabytes (2^34 bytes), time= 368 seconds
  no anomalies in 226 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 32 gigabytes (2^35 bytes), time= 801 seconds
  no anomalies in 235 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 64 gigabytes (2^36 bytes), time= 1825 seconds
  no anomalies in 247 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 128 gigabytes (2^37 bytes), time= 3980 seconds
  no anomalies in 258 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 256 gigabytes (2^38 bytes), time= 6931 seconds
  no anomalies in 267 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 512 gigabytes (2^39 bytes), time= 12961 seconds
  no anomalies in 279 test result(s)

rng=RNG_stdin, seed=0xff13eeed
length= 1 terabyte (2^40 bytes), time= 25046 seconds
  no anomalies in 290 test result(s)
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads