Thread View: pl.comp.lang.c
42 messages
42 total messages
Started by M.M.
Tue, 24 Dec 2019 19:25
Optymalizacja kodu
Author: M.M.
Date: Tue, 24 Dec 2019 19:25
Date: Tue, 24 Dec 2019 19:25
360 lines
12534 bytes
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
Author: Maciek Godek
Date: Wed, 25 Dec 2019 10:55
Date: Wed, 25 Dec 2019 10:55
17 lines
2833 bytes
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
Author: Maciek Godek
Date: Wed, 25 Dec 2019 11:01
Date: Wed, 25 Dec 2019 11:01
8 lines
1889 bytes
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
Author: M.M.
Date: Wed, 25 Dec 2019 13:25
Date: Wed, 25 Dec 2019 13:25
45 lines
3634 bytes
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
Author: Maciek Godek
Date: Wed, 25 Dec 2019 19:52
Date: Wed, 25 Dec 2019 19:52
40 lines
3609 bytes
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
Author: M.M.
Date: Wed, 25 Dec 2019 20:49
Date: Wed, 25 Dec 2019 20:49
44 lines
3837 bytes
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
Author: Maciek Godek
Date: Wed, 25 Dec 2019 21:49
Date: Wed, 25 Dec 2019 21:49
46 lines
4078 bytes
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
Author: (fir)
Date: Thu, 26 Dec 2019 01:01
Date: Thu, 26 Dec 2019 01:01
69 lines
5322 bytes
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
Author: (fir)
Date: Thu, 26 Dec 2019 01:10
Date: Thu, 26 Dec 2019 01:10
52 lines
4203 bytes
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
Author: (fir)
Date: Thu, 26 Dec 2019 01:18
Date: Thu, 26 Dec 2019 01:18
64 lines
4611 bytes
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
Author: M.M.
Date: Thu, 26 Dec 2019 03:46
Date: Thu, 26 Dec 2019 03:46
105 lines
6605 bytes
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
Author: M.M.
Date: Thu, 26 Dec 2019 04:00
Date: Thu, 26 Dec 2019 04:00
121 lines
6777 bytes
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
Author: M.M.
Date: Thu, 26 Dec 2019 04:03
Date: Thu, 26 Dec 2019 04:03
79 lines
4890 bytes
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
Author: (fir)
Date: Thu, 26 Dec 2019 08:43
Date: Thu, 26 Dec 2019 08:43
99 lines
6181 bytes
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
Author: Wojciech Muła
Date: Thu, 26 Dec 2019 08:57
Date: Thu, 26 Dec 2019 08:57
1 lines
1449 bytes
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
Author: (fir)
Date: Thu, 26 Dec 2019 09:00
Date: Thu, 26 Dec 2019 09:00
20 lines
3009 bytes
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
Author: (fir)
Date: Thu, 26 Dec 2019 09:05
Date: Thu, 26 Dec 2019 09:05
23 lines
3308 bytes
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
Author: (fir)
Date: Thu, 26 Dec 2019 09:12
Date: Thu, 26 Dec 2019 09:12
28 lines
4089 bytes
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
Author: Maciek Godek
Date: Thu, 26 Dec 2019 10:14
Date: Thu, 26 Dec 2019 10:14
26 lines
2921 bytes
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
Author: M.M.
Date: Fri, 27 Dec 2019 06:28
Date: Fri, 27 Dec 2019 06:28
5 lines
1634 bytes
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
Author: M.M.
Date: Fri, 27 Dec 2019 07:44
Date: Fri, 27 Dec 2019 07:44
169 lines
8068 bytes
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
Author: (fir)
Date: Fri, 27 Dec 2019 18:48
Date: Fri, 27 Dec 2019 18:48
172 lines
8594 bytes
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
Author: M.M.
Date: Fri, 27 Dec 2019 19:12
Date: Fri, 27 Dec 2019 19:12
10 lines
1974 bytes
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
Author: (fir)
Date: Fri, 27 Dec 2019 19:18
Date: Fri, 27 Dec 2019 19:18
13 lines
2348 bytes
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
Author: M.M.
Date: Fri, 27 Dec 2019 20:54
Date: Fri, 27 Dec 2019 20:54
22 lines
2866 bytes
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
Author: (fir)
Date: Fri, 27 Dec 2019 21:01
Date: Fri, 27 Dec 2019 21:01
23 lines
3216 bytes
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
Author: M.M.
Date: Sat, 28 Dec 2019 02:44
Date: Sat, 28 Dec 2019 02:44
38 lines
3804 bytes
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
Author: (fir)
Date: Sat, 28 Dec 2019 09:11
Date: Sat, 28 Dec 2019 09:11
67 lines
5685 bytes
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
Author: (fir)
Date: Sat, 28 Dec 2019 09:26
Date: Sat, 28 Dec 2019 09:26
70 lines
6153 bytes
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
Author: M.M.
Date: Sat, 28 Dec 2019 10:50
Date: Sat, 28 Dec 2019 10:50
81 lines
6889 bytes
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
Author: (fir)
Date: Sat, 28 Dec 2019 10:50
Date: Sat, 28 Dec 2019 10:50
73 lines
6804 bytes
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
Author: (fir)
Date: Sat, 28 Dec 2019 10:52
Date: Sat, 28 Dec 2019 10:52
84 lines
7310 bytes
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
Author: (fir)
Date: Sat, 28 Dec 2019 10:58
Date: Sat, 28 Dec 2019 10:58
91 lines
8486 bytes
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
Author: (fir)
Date: Sat, 28 Dec 2019 11:11
Date: Sat, 28 Dec 2019 11:11
110 lines
9616 bytes
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
Author: (fir)
Date: Sat, 28 Dec 2019 11:12
Date: Sat, 28 Dec 2019 11:12
113 lines
10152 bytes
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
Author: M.M.
Date: Sun, 29 Dec 2019 04:38
Date: Sun, 29 Dec 2019 04:38
121 lines
10648 bytes
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
Author: (fir)
Date: Sun, 29 Dec 2019 04:50
Date: Sun, 29 Dec 2019 04:50
124 lines
11410 bytes
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
Author: M.M.
Date: Sun, 29 Dec 2019 05:36
Date: Sun, 29 Dec 2019 05:36
130 lines
11896 bytes
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
Author: (fir)
Date: Sun, 29 Dec 2019 11:20
Date: Sun, 29 Dec 2019 11:20
190 lines
13858 bytes
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
Author: Wojciech Muła
Date: Sun, 29 Dec 2019 19:00
Date: Sun, 29 Dec 2019 19:00
14 lines
2078 bytes
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
Author: M.M.
Date: Wed, 01 Jan 2020 16:27
Date: Wed, 01 Jan 2020 16:27
44 lines
3476 bytes
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
Author: M.M.
Date: Thu, 02 Jan 2020 05:14
Date: Thu, 02 Jan 2020 05:14
354 lines
19788 bytes
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