Optymizacja czasowa rozpadu połowicznego słowa danych

0

Jaka metoda powinna być uznawana za wzorcową do takich zastosowań?

 
1)	///////////////////////////////////////////////
	MSB:= l div 256;
	LSB:= l mod 256;

2)	/////////////////////////////////////////////// 
	LSB:= byte(l);
  	MSB:= byte(l shr 8); 

3)	///////////////////////////////////////////////
	LSB:= l and 255;
  	MSB:= l and 65280; 

4)	///////////////////////////////////////////////	

type

Unia_Word_Big_Endian = record  
                         case word of
                              1: (word: word);
                              2: (MSB,LSB: byte);
                         end;

var
	
WordBigEndian: Unia_Word_Big_Endian;

begin
	WordBigEndian.word:=l;
			
end.

0

Przykład 4 jest w kontekście FPC niepoprawny: Po pierwsze brakuje packed po drugie unia w FPC NIE służy do dzielenia/łączenia danych (pytałem developerów).
Przykład 1 używa dzielenia, wolno.
Przykład 2 jest najszybszy z wymienionych.
Przykład 3 generuje złe wyniki.

  1. Jest jeszcze jeden sposób: Lo i Hi Które powinny być dosyć optymalne.
0

Po pierwsze brakuje packed po drugie unia w FPC NIE służy do dzielenia/łączenia danych
ale jeżeli jest packed to „ma obowiązek” działać…

0
Azarien napisał(a):

ale jeżeli jest packed to „ma obowiązek” działać…

Oj właśnie nie. Nigdy dokładnie sprawie się nie przyglądałem, ale osoby związane z FPC odradziły używania unii do dzielenia/łączenia typów gdyż powoduje to błędy i nie do tego służy. Sam parę razy się na to nadziałem. Nie pytaj dlaczego tak jest, bo nie wiem, ale tak jest jak wynika z moich testów i słów developerów.
Kiedyś (~2.2.0) to działało, ale od ok. wersji 2.4.0 miałem parokrotnie z tym problemy i za każdym razem kończyło się na zmianie unii na inne instrukcje.

0

wersja 1, bo naturalna, a kompilator zrobi to po swojemu.

1
Xitami napisał(a):

wersja 1, bo naturalna, a kompilator zrobi to po swojemu.

Nie zgodzę się. Naturalna to jest wersja 5, czyli Lo i Hi. Moim zdaniem zrzucanie nawet tak prostych działań na optymalizator to głupota. Mi dłużej zajęło zrozumienie instrukcji 1 niż chociażby 2.
Osobiście zawsze stosuję and i shr / shl, chyba że dzielimy word, wtedy jest Lo i Hi.

0

Wersja z unią może być zawodna w FPC, bo zakłada określoną kolejność bajtów w słowie.
A jest ona niestety zmienna - w zależności od platformy.

Najlepiej rób tak jak napisał 123:

  • Lo() / Hi() dla dzielenia word
  • and / shr dla dzielenia innych wartości
0
  • kłopoty mogą powstać gdy użyjesz wskaźnik do unii przy włączonych pewnych optymalizacjach.
  • FPC oferuje lo() i hi() nie tylko dla typu word.
  • jeżeli bawimy się bitami, wtedy shr i and ma sens
  • jeżeli dzielimy liczby, nawet przez potęgę dwójki piszemy div a resztą zajmie się kompilator
0
  • kłopoty mogą powstać gdy użyjesz wskaźnik do unii przy włączonych pewnych optymalizacjach.

Nie tylko, gdy tworzyłem unię do relokacji (format $XYYY) to nie działały one poprawnie.

  • jeżeli dzielimy liczby, nawet przez potęgę dwójki piszemy div a resztą zajmie się kompilator

Nie kompilator a optymalizator. I tylko przy włączonej optymalizacji. Jeżeli w rzeczywistości to ma odpowiadać za dzielenie (tj. ma to uzasadnienie matematyczne) to jestem za pisaniem dzielenia. Jeżeli natomiast zależy nam na działaniu na bitach jestem za pisaniem shr. I to chyba ty napisałeś :p .

0

Szukałem opisu właściwego zastosowania unii (rekordu wariantowego) z tego co znalazłem wynika,że można go skutecznie stosować
do dzielenia bajtów Big endian (MSB,LSB) oraz zamiany na Little endian (LSB,MSB) jest to metoda wydajna i zgodna z prawidłami dobrego programowania.

Ale wracając do tematu dzielenia słowa przy pomocy hi() i lo() idea kompatybilności kompilatora z danym typem CPU a dokładniej
z jego organizacją zapisu bajtów sypie się gdy chcemy ponownie sprawnie i wydajnie połączyć bajty w słowo no bo jak to zrobić
mnożenie? ( czasowo wypada tragicznie ) ???

0
  1. poza bolesnymi wyjątkami, działa bardzo dobrze. pÓÓÓÓki kompilator ma wrażenie, że wie co robisz działa bardzo dobrze.

  2. Z pewnością twój kompilator lepiej logarytmuje niż Ty. Potrafi sensownie zastąpić mnożenie shiftem, ale nie tylko mnożenie. Dzielenie przez stałą da się zastąpić mnożeniem, nie tylko w rzeczywistych, ale i wśród całkowitych.

0

Szukałem opisu właściwego zastosowania unii (rekordu wariantowego) z tego co znalazłem wynika,że można go skutecznie stosować
do dzielenia bajtów Big endian (MSB,LSB) oraz zamiany na Little endian (LSB,MSB) jest to metoda wydajna i zgodna z prawidłami dobrego programowania.

Powiedz to developerom FPC. Nie ufam uniom.

Ale wracając do tematu dzielenia słowa przy pomocy hi() i lo() idea kompatybilności kompilatora z danym typem CPU a dokładniej
z jego organizacją zapisu bajtów sypie się gdy chcemy ponownie sprawnie i wydajnie połączyć bajty w słowo no bo jak to zrobić
mnożenie? ( czasowo wypada tragicznie ) ???

Znowu shr, shl i and. Myśl...

  1. poza bolesnymi wyjątkami, działa bardzo dobrze. pÓÓÓÓki kompilator ma wrażenie, że wie co robisz działa bardzo dobrze.

Gdyby kompilator wiedział co robisz to byłby w stanie wykryć twoje błędy logiczne i samemu pisać programy. Nie wiem jak ty, ale ja traktuję kompilator jako narzędzie nie jako coś co myśli i wie.

  1. Z pewnością twój kompilator lepiej logarytmuje niż Ty. Potrafi sensownie zastąpić mnożenie shiftem, ale nie tylko mnożenie. Dzielenie przez stałą da się zastąpić mnożeniem, nie tylko w rzeczywistych, ale i wśród całkowitych.

4/2=2
4*(1/2)=2 <- Ułamek. Nie da się całkowitego dzielenia zamienić na całkowite mnożenie (in most cases).
Gdy nie chodzi nam o mnożenie ale o przesuwanie bajtów to proponuję jednak użyć shl i shr, bo mniej gmatwają kod. Zwłaszcza jeżeli mamy pisać *256.

0

Nie ufasz, znaczy wyznawcy Twojej religii...

Zachęcasz do myślenia, to jest OK. Co prawda nie wiem o co chodzi.

  1. No cóż, myślisz chyba mniej niż nowoczesny kompilator

  2. A no bo widzisz, kompilatory więcej wiedzą o dzieleniu niż Ty.

0

Skoro straciłem już tyle czasu na testy to macie tu wesołą twórczość kompilatorów wyniki są ciekawe.
Kolega chyba miał racje wynikowy kod HiSoft Pascal mnie powalił zapewne "lepiej logarytmuje " od nas wszystkich.
Jeśli ktoś to rozumie to podziwiam....

Jakoś nie widać w tym kodzie waszych ulubionych rotacji jedynie x86 nadrabia błędy architektury rotacjami.
Czy ktoś ma Pascal na ARM'a zapis assemblerowy pewnie zamykałby jeden rozkaz....

 

//Kompilator Borland Delphi 7 kod wynikowy CPU x86 taktowanie 3200 Mhz

Unit1.pas.30: i:=$aa55;

mov ax,$aa55

Unit1.pas.31: j:=(256*hi(i))+lo(i);

mov edx,eax
shr dx,$80
mov esi,edx
shl esi,$80
and ax,$00ff
add si,ax


//Kompilator HiSoft Pascal Ver 1.2 (1987r) kod wynikowy CPU MC68000 taktowanie 7.14 Mhz


<7> i:=$AA55;

move.w #$AA55,d0

<8> j:=(256*hi(i))+lo(i);

clr.w d1
move.b d0,d1
or.w d1,d0



//Kompilator MC51 Development System Ver 5.3.4 (C)2012 Dr.J.Rathlev kod Wynikowy CPU 8051 taktowanie 11.592 Mhz

(4) i:=$aa55;

MOV i,#55H
MOV i+1,#0AAH

(5) j:=(256*hi(i))+lo(i);

MOV j,i
MOV A,#0AAH
ADDC A,#0
MOV j+1,A

0

delphi: dla schiftów jest chyba 5 bitów, ale jeżeli nie to prawie OK, prawie

HiSoft: potwierdza, że nie na darmo lubiłem go na Spectrum, prawie wie co robi
dorobiłem mu nawet pracę z dyskietką, chyba 3"

MC51: ciekawym, do czego to adC, to chyba gruby błąd

FPC mnie rozczulił gdy zobaczyłem, że dla odd() jest CALL...

0

Nie ufasz, znaczy wyznawcy Twojej religii...

Oczywiście, moje doświadczenia są całkowicie bezsensowne.

Zachęcasz do myślenia, to jest OK. Co prawda nie wiem o co chodzi.

Tak, zachęcam do myślenia. Tak skomplikowanego jak shl 8. O boże, czacha dymi.

  1. No cóż, myślisz chyba mniej niż nowoczesny kompilator

Skoro uważasz że kompilatory myślą to nie myślisz.

  1. A no bo widzisz, kompilatory więcej wiedzą o dzieleniu niż Ty.

Jasne, kompilatory jeszcze pewnie lepiej wiedzą co chcę napisać. Po co w ogóle dawać im kod. Dawajmy im pomysły one pomyślą o kodzie.
Niestety nie miałem styczności z kompilatorem mądrzejszym ode mnie.

move.w #$AA55,d0
clr.w d1
move.b d0,d1
or.w d1,d0

Przyznam że ładnie.

FPC mnie rozczulił gdy zobaczyłem, że dla odd() jest CALL...

Srsly?

project1.lpr:8  for i:=1 to 10 do if odd(i) then inc(j);
00401417 66ba0100                 mov    $0x1,%dx
0040141B 664a                     dec    %dx
0040141D 8d7600                   lea    0x0(%esi),%esi
00401420 6642                     inc    %dx
00401422 89d0                     mov    %edx,%eax
00401424 83e001                   and    $0x1,%eax
00401427 84c0                     test   %al,%al
00401429 7402                     je     0x40142d <main+45>
0040142B 6643                     inc    %bx
0040142D 6681fa0a00               cmp    $0xa,%dx
00401432 72ec                     jb     0x401420 <main+32>

Nie chwal już się nieumiejętnością jego użycia.

0
  • ależ, to właśnie jest religia!
  • napisałem, że nie wiem o co chodzi.
  • mam wrażenie że jesteśmy z innej bajki
  • a no bo widzisz, ja nie o myśleniu ale o dzieleniu
  • może to było kiedyś, ale zapamiętałem mu ten CALL w miejsce odd(), było bez dwu zdań.
0
  • może to było kiedyś, ale zapamiętałem mu ten CALL w miejsce odd(), było bez dwu zdań.

No i co z tego. Pewnie kompilowałeś na -O0 i dlatemu zrobił tak żeby łatwo było debuggować i zachował call... Ustaw na -O3 -Or -Ou i wtedy oceniaj przez niego wygenerowany kod. Chyba nie uważasz że kompilator powinien generować optymalny kod gdy wyraźnie ustawiło mu się brak optymalizacji. No chyba że kompilator powinien wiedzieć lepiej...

  • mam wrażenie że jesteśmy z innej bajki
  • a no bo widzisz, ja nie o myśleniu ale o dzieleniu

Byćmoże i jesteśmy z innej bajki. Nie wierzę w to, że kompilatory są mądrzejsze niż ludzie, bo są tworzone przez ludzi (a mądrość obejmuje też wiedzę o dzieleniu). Nie mniej przyznam że kod wygenerowany przez HiSoft mnie zaskoczył.
Nie jest też tak że nie doceniam optymalizacji, ale uważam że chociażby czytelniej jest użyć shr/shl. Zresztą współczesne kompilatory wcale nie wymyśliły nic lepszego.

  • ależ, to właśnie jest religia!

Religia czego. Bardzo ciekaw jestem w co wierzę.

  • napisałem, że nie wiem o co chodzi.

Musiałbyś napisać czego nie wiesz żebym ci to objaśnił. I niestety ja również niezbyt rozumiałem twoją wypowiedź.

0
  • tak myślę, że to mogło być debug i być może size, a może było to strasznie dawno
  • kompilatory mają małpią zręcznoś, i potrafią robić takie sztuczki, że nawet wójt z Napierstkowa by się zdziwił.
  • odwołujesz się do swojego doświadczenia, to właśnie jest podstawą wszystkich religii
  • napisałem, że nie wiem, bo sam zobacz, ktoś tam coś tam o tragicznym mnożeniu.
0
  • kompilatory mają małpią zręcznoś, i potrafią robić takie sztuczki, że nawet wójt z Napierstkowa by się zdziwił.

To że raz kompilator zachował się mądrze nie znaczy że następnym razem też tak będzie. Nie bawię się w rozmyślanie jak to ładnie mi optymalizator zrobi ten kod tylko piszę logiczny i w miarę optymalny kod. Nie używam operatorów shl i shr jeżeli nie chodzi mi o przesuwanie bajtów, ale jeżeli o to chodzi to ich używam. Proste, logiczne i przewidywalne. Wszystko czego optymalizatory mogą chcieć.

  • odwołujesz się do swojego doświadczenia, to właśnie jest podstawą wszystkich religii

A mi się wydawało że podstawą religii jest wiara. Pierniczysz trzy po trzy.

  • napisałem, że nie wiem, bo sam zobacz, ktoś tam coś tam o tragicznym mnożeniu.

Nadal nie rozumiem.

0
  • właśnie to napisałem w pierwszym poście
  • w co? jakoś tu nie pomyślałeś
  • stary, cały kosmos nie obraca się wokół ciebie, to przecie było do kogoś co coś tam bredził.
0
  • właśnie to napisałem w pierwszym poście

No i ja również może i nie w pierwszym ale którymś.

  • w co? jakoś tu nie pomyślałeś

Nie umiesz robić pełnych zdań? By się ciebie łatwiej czytało.
Wiara w pewne rzeczy. Wiara raczej dotyczy doświadczeń innych. Czy to że wierzę w swoje doświadczenia powoduje że mam swoją religię? I don't think so.
Czy ty masz coś przeciwko doświadczeniom? Nie lubisz ich? A może się nimi nie kierujesz? Nie rozumiem po co nam ta rozmowa o religiach o_O.

  • stary, cały kosmos nie obraca się wokół ciebie, to przecie było do kogoś co coś tam bredził.

To dlatego nie rozumiałem? To ma sens. W przyszłości postaraj się jasno zwracać do poszczególnych osób...

0
  • !
  • pewnie, że wierzę w doświadczenie. Tyle, że "nie ufam" to wiara w magię.

No tak, był by chyba łatwiej i bardziej elegancko gdybym "cytował", przepraszam nie chciało mi się.
Za to odpowiadałem precyzyjnie w punktach.

0
  • pewnie, że wierzę w doświadczenie. Tyle, że "nie ufam" to wiara w magię.

Wiara w magię to wierzenie że kompilator będzie generował super kod. "Nie ufam" powiedziałem powiedziałem półserio. Skróty myślowe FTW. Zresztą nevermind. Gadamy o niczym i o religii czyli w sumie też o niczym.

0

O! A teraz możemy iść na piwo! Twoje zdrowie.

0

Mam nadzieje że to koniec historii CALL / odd() w FPC :)

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