kategoria: ANSI C
[#31] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Don_Adan, post #30

Mam wrażenie, że koniecznie chcesz udowodnić wyższość asemblera. Nie ma potrzeby, asm i tak w końcu wygra, to tylko kwestia poświęconego czasu. Z tym, że ten pomysł z trzymaniem 3 cyfr wynikowych w jednym rejestrze też można zapisać w C, ba nawet SWAP zostanie użyty. Ale chyba już mi się trochę nie chce.
1
[#32] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Krashan, post #31

Nie, nic nie chce udowodnic.
Po prostu patrzac na niektory kod w ASM tworzony przez kompilatory jak rowniez przez niektorych koderow drazni on moje oczy jak na niego patrze.
No i watek jest pt. "jak wydajnie zamienic...", a nie "jak zamienic".
Choc musze przyznac ze kompilator az tak zle tego nie zrobil.
Tylko trzeba mu odpowiednie optymalizacje ustawic/wybrac.
Jedunie sie tak zastanawiam, ze jak sie pisze w C, to wybrana optymalizacja jest dobra na wszystko, czy tez mozna zmieniac ja dla kazdej procedury z osobna. Bo raczej watpie, zeby jeden typ optymalizacji byl dobry na caly kod.
[#33] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Krashan, post #31

A zastanawia mnie jeszcze jedna rzecz: wiadomo, że dzielenie przez 10 zajmuje bardzo dużo cykli, ale jedno dzielenie wystarczy by wyodrębnić cyfrę i wyznaczyć wartość do dalszych obliczeń, więc może i takie podejście też jest dobre:

; D0 - liczba
; A0 - wskazuje za końcem bufora na cyfry

MOVEQ  #10,D1
.loop:
DIVS.W D1,D0
SWAP   D0
MOVE.B D0,-(A0)
SWAP   D0
EXT.L  D0
BNE.S  .loop

RTS

Jeszcze dodam, że okazało się, że procesor MC68020+ ma wbudowaną konwersję do pakowania i rozpakowywania BCD: komendy PACK i UNPK.
[#34] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Hexmage960, post #33

Tylko dla np. 243 bedziesz mial 3 dzielenia. A to duzo, przecietnie beda 2 dzielenia, tez wolno.
O ile dobrze pamietam to ominiecie 3 dzielen w procedurze miksujacej dalo mi 1kHz wiecej na 68000.
Po prostu tylko sprawdzalem, czy w poprzednim wejsciu w procedure miksujaca byl ten sam period/okres uzyty.
Jak byl taki sam, to nie robilem/liczylem tego jeszcze raz.
No bo po co liczyc to samo jeszcze raz, jesli wynik bedzie taki sam.
Tutaj tez pewnie mozna pomijac ta procedure.
Wszystko zalezy jak czesto wyswietlana wartosc sie zmienia.
Jesli jest niezmieniona, to po co to liczyc jeszcze raz?
Po prostu pominac.
Wystarczy jakis cmp.w uzyc przed wejsciem w procedure.
[#35] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Krashan, post #27


Uważam, że z kompilatorów C, które można sensownie używać na rzeczywistej (trochę dopalonej, ale bez przesady) Amidze, GCC 2.95.3 jest najlepszy. Do tego umie w C++.

A co z SASem ? Kiedyś go używałem ale moja wiedza związana z nim była mikra i w sumie tylko generowałem pliki asm by zobaczyć jak sobie daje radę. Ale muszę przyznać że gcc 2.95.3 zrobił na mnie wrażenie, bo potrafi zrobić użytek z dbxx, bxx, sxx. Jeszcze jakbym wiedział jak wyłączyć to trzymanie się amigowego api, czyli wywalenie wrzucania d2-d7/a2-a6 na stos to bym się cięszył jeszcze bardziej. Najbardziej mnie boli że nie ma c99, mam na myśli deklarowanie zmiennych w dowolnym momencie. I czytanie plików asm wygenerowanych przez opcję -S też trochę boli.

Też pomęczyłem trochę gcc i udało mi się zrobić taki kod
_NumToStr:	move.l	d2,-(sp)
	moveq	#100,d2
	moveq	#47,d1
lbC0000AA:	addq.b	#1,d1
	sub.w	d2,d0
	bpl.s	lbC0000AA
	add.w	d2,d0
	move.b	d1,(a0)+
	moveq	#47,d1
	moveq	#10,d2
lbC0000B8:	addq.b	#1,d1
	sub.w	d2,d0
	bpl.s	lbC0000B8
	move.b	d1,(a0)+
	add.b	#58,d0
	move.b	d0,(a0)+
	clr.b	(a0)
	move.l	(sp)+,d2
	rts


Z takiego
void NumToStr(short liczba, char *bufor)
{
	register short sto asm("d2") = 100 ;
	char k = 47;
	
	do
	{
		k++;
		liczba -= sto;
	}
	while (liczba >= 0);

	liczba += sto;
	*bufor++ = k;
	k = 47;

	{
	short dycha = 10;
	do
	{
		k++;
		liczba -= dycha;
	}
	while (liczba >= 0);
	}
	
	*bufor++ = k;
	*bufor++ = 58 + liczba;
	*bufor = 0x00;
}


Uważam że kod jest dla mnie bardzo dobry.

@Hexmage960

A zastanawia mnie jeszcze jedna rzecz: wiadomo, że dzielenie przez 10 zajmuje bardzo dużo cykli, ale jedno dzielenie wystarczy by wyodrębnić cyfrę i wyznaczyć wartość do dalszych obliczeń, więc może i takie podejście też jest dobre:

W przypadku 68000 dzielenie zżera prawie 140 cykli. tyle cykli zajmię najgorszy przypadek w podejściu z odejmowaniem dla jednej cyfry (chodzi o to że któraś pętla wykona się 10 razy ). A zważywszy że wykonujesz dzielenie nawet w przypadku jednocyfrowej liczby, to takie podejście nie jest dobre. Dla każdego przypadku żżera 550 cykli, a podejściu z odejmowaniem to w najgorszym razie będzię poniżej 200 cykli (przypadek bajtu który równa 190). Szansa najgorszego przypadku jest rzędu 4% ( mamy 256 możliwości i 10 przypadków 19x).

Ostatnia aktualizacja: 26.09.2024 13:08:07 przez asman
[#36] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@asman, post #35

I tak wygladajacy po skompilowaniu kod C mi sie podoba.
1
[#37] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@asman, post #35

Jeszcze jakbym wiedział jak wyłączyć to trzymanie się amigowego api, czyli wywalenie wrzucania d2-d7/a2-a6 na stos to bym się cięszył jeszcze bardziej.
Najbardziej kompleksowym rozwiązaniem tego problemu jest przekonfigurowanie kompilatora i zbudowanie go ze źródeł. Bo to co chcesz zrobić, to zmiana ABI. Niemniej da się to zrobić trochę na partyzanta. Wcześniej o tym nie wiedziałem, bo piszę pod system, więc wygodniej mi jest trzymać się standardowego ABI. Ale do rzeczy.

Jest taka opcja -fcall-used-<rejestr>, która powoduje, że dany rejestr jest traktowany jako scratch register w funkcjach (tak jak d0/d1/a0/a1 standardowo). Na przykład skompilowanie naszego męczonego kodu z dodatkiem opcji -fcall-used-d2 spowoduje, że w funkcji nie będzie przechowywany rejestr d2. Co więcej, jeżeli damy mu -fcall-used-d2 -fcall-used-d3, to kompilator nie będzie już kombinował z używaniem a1 do trzymania naszej "setki", leci MOVEQ #100, d3 i pojechali. Oczywiście w tym przypadku również d3 nie jest przechowywany na stosie.

Trzeba sobie jednak zdawać sprawę z tego, że w miarę jak będziemy zabierać kompilatorowi rejestry przechowywane przez funkcje, to w ich funkcjach nadrzędnych może mu zabraknąć rejestrów na zmienne lokalne, których zasięg jest "ponad wywołaniami funkcji" i zacznie je trzymać na stosie, z wszystkimi tego konsekwencjami dla wydajności. I może się okazać, że zamienił stryjek.

Trzeba też pamiętać, że wywołania funkcji OS-a mają gdzieś te parametry i zawsze przechowują to, co zawsze.

Ostatnia aktualizacja: 26.09.2024 18:16:42 przez Krashan
1
[#38] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Krashan, post #27

O vbcc mam swoje dość niepochlebne zdanie, które po raz kolejny się potwierdziło. Uważam, że z kompilatorów C, które można sensownie używać na rzeczywistej (trochę dopalonej, ale bez przesady) Amidze, GCC 2.95.3 jest najlepszy. Do tego umie w C++.

To C++ to w dzisiejszych czasach bardzo "wiekowe" C++ .. ta wersja GCC 2.95.3 miała premierę w 2001 roku, wiec wspiera C++98 .. od tego czasu w C++ pojawiło się bardzo wiele poważnych zmian i usprawnień, które bardzo mocno zmieniają sposób pisania w C++ w porównaniu z tym z lat 90-tych.
Na dzisiejsze standardy jak bym powiedział wręcz przeciwnie, że GCC 2.95.3 .. nie umie C++ ... :P

Ostatnia aktualizacja: 26.09.2024 18:16:53 przez Rafael/ARMO
[#39] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Rafael/ARMO, post #38

To jest problem ludzi, którzy w pracy piszą we współczesnym C++. Mi to w niczym nie przeszkadza, bo nie mam zielonego pojęcia o niczym nowszym w C++ niż jest w książce Stroustrupa. A to wystarcza, żeby pisało się znacznie wygodniej niż w C. Zresztą kompiluję bez biblioteki standardowej, więc jeszcze muszę wyłączyć wyjątki i RTTI. To już w ogóle odjazd, ale mi pasuje.
1
[#40] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Krashan, post #39

To jest problem ludzi, którzy w pracy piszą we współczesnym C++. Mi to w niczym nie przeszkadza, bo nie mam zielonego pojęcia o niczym nowszym w C++ niż jest w książce Stroustrupa

Wytłumacz dlaczego to jest problem ludzi którzy w pracy piszą we współczesnym C++? Nie rozumiem tego stwierdzenia.
Czy korzystanie z nowszej wersji języka jest problemem? Czy w takim razie problemem ludzi jest pisanie pod Amiga OS3+? Bo pod 2.0 przecież można "wszystko" zrobić, co jest w 2.0 RKM, za to wystarcza żeby było wygodniej niż w 1.3?
Poza tym Stroustrup do dzisiaj pisze książki o C++ (np.: "Język C++ kompendium wiedzy") w których opisuje co jest nowego w kolejnych odsłonach C++, jakie są zalecenia etc.
[#41] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Krashan, post #37

@Krashan

Jest taka opcja -fcall-used-<rejestr>, ...


Co za pyszna opcja, przetestuje sobie, pięknie dziękuje. Oczywiście zdaję sobię sprawę z konsekwencji jakie to może nieść.

@Don Adan
I tak wygladajacy po skompilowaniu kod C mi sie podoba.

Mi także. Jeśli dodamy te przepyszne opcje -fcall-used to zapowiada się ciekawie.

@Krashan

To jest problem ludzi, którzy w pracy piszą we współczesnym C++. Mi to w niczym nie przeszkadza, bo nie mam zielonego pojęcia o niczym nowszym w C++ niż jest w książce Stroustrupa.

Dla mnie jeśli ten C++ z gcc 2.9 generuje sensowny kod to czemu nie, jeszcze tylko by mi się przydał jakiś taki przykładzik jak to się popełnia i obadam sobie sprawę. Ja mam małe wymagania jeśli chodzi o takie rzeczy.

Muszę przyznać że coraz bardziej mi się podoba ten gcc. A tak się broniłem przed nim, ehhh, po raz kolejny osioł ze mnie wychodzi.
[#42] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@asman, post #35

@Asman

Przyznam, że nie wiedziałem że dla 68000 dzielenie jest aż tak kosztowne. Patrzyłem na 68020 gdzie jest ok. 50 cykli.

@Don Adan

Jasne, że bardzo fajna jest optymalizacja polegająca na liczeniu tylko i wyłączenie tego co potrzeba. Tutaj najlepiej według mnie dodawać cyfry za pomocą BCD, jeżeli faktycznie musimy robić dużo tego typu operacji - dlatego wyszedłem z tą propozycją. Dzielenie DIVS można zaś zastosować, gdy jest lepszy procesor.

Podałem tylko własne propozycje, które tak, jak propozycje kolegów na pewno mają swoje wady i zalety.

Ja słyszałem, że format BCD wprowadzono ze względu na zastosowanie komputerów w finansach.

@Krashan

Ja na studiach licencjackich miałem dwa przedmioty o "Programowaniu Obiektowym" i tam poznałem po raz pierwszy dogłębnie język C++. Nasz profesor nie omawiał jednakże nowinek. Mieliśmy szablony, kontenery, strumienie, manipulatory itp.

Na magisterskich pojawił się przedmiot "Kompilatory" i - o ile liznąłem już wcześniej ten temat zapoznając się z kompilatorami gier tekstowych z lat 80. na Amidze - to dopiero tutaj dogłębnie zapoznałem się z tym tematem.

Jest to nie lada ciekawy temat - i zaciekawi chyba każdego programistę. Z książek jakich korzystaliśmy, to tzw. "Dragon Book", który kupiłem sobie w papierowej edycji, bardzo nowe wydanie (z roku 2019). Na zaliczenie przedmiotu były 4 projekty - skaner, parser, obsługa błedów w parserze i generator kodu bardzo prostego języka.

(Chyba Asman pytał wcześniej o książkę o kompilatorach - to polecam - książkę "Kompilatory - reguły, metody, narzędzia" - wydawnictwa PWN).

W tej kompleksowej książce piszą też o optymalizacji ale tego nie czytałem.

Ciekawym jest które z pomysłów które pojawiły się w wątku wybrał jako rozwiązanie nasz kolega - Mateusz. Jeżeli stawia na C, to padło szereg propozycji. Ja podałem te, w których musimy posiłkować się asemblerem, czy to BCD, czy dzielenie z resztą.

Ja przyznam, że ja korzystam czasami z dzielenia i reszty oraz sprintf(). Ale ja mam i celuję w 68030 z FAST, a poza tym tych operacji dzielenia nie jest aż tak dużo.

Akurat tutaj dzielenie będzie powtarzane tylko kilka razy przy liczeniu kilku wartości - jak również Mateusz celuje w lepsze procesory - więc pewnie nie będzie z tym dużego problemu.

Ostatnia aktualizacja: 26.09.2024 23:06:54 przez Hexmage960
[#43] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Hexmage960, post #42

Dzielenie zuzywa najwiecej cykli na 68k.
Najlepiej jest zawsze dzielic przez wielokrotnosci 2, bo wtedy przesuniecia mozna uzywac.
Co do pomijania kodu, to podejrzewam, ze duzo gier portowanych liczy wielokrotnie rzeczy, juz policzone wczesniej.
Do pomijania liczenia mozna w przypadku procedury c2p uzyc MMU tak jak to robia sterowniki do Shapeshiftera/Fusiona.
One bodaj pomijaja liczenie linii, ktore sie nie zmienily.
Ale ja sie na MMU nie znam.
A w przypadku takiej procedury to mozna np. zrobic tak:

; input D0 (word)
; output D1 (longword)
; D2, A0 temp

 cmp.w D0,Last
 beq.b skip
 move.w D0,Last
 move.l #$FFFF00FF,D1 ; wartosci poczatkowe to $FF dla kazdej z 3 cyfr
 moveq #100,D2
B100
 addq.b #1,D1
 sub.w D2,D0
 bcc.b B100
 add.w D2,D0
 swap D1 ; pierwsza cyfra ustawiona
 moveq #10,D2
 lea $100.W,A0
B10
 add.w A0,D1 ; druga cyfra ustawiana
 sub.w D2,D0
 bcc.b B10
 add.w D2,D0
 move.b D0,D1 ; trzecia cyfra ustawiona
skip
 rts

Last
 dc.w 0


Albo po prostu wywolywac procedure tylko jak sie zmieni wartosc do wyswietlenia.
Zalezy do czego ona ma byc uzywana.
[#44] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Rafael/ARMO, post #40

Kontynuacja dyskusji będącej offtopem i prowadzonej w napastliwym tonie, jest dla mnie bezcelowa.
[#45] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@asman, post #41

Dla mnie jeśli ten C++ z gcc 2.9 generuje sensowny kod to czemu nie, jeszcze tylko by mi się przydał jakiś taki przykładzik jak to się popełnia i obadam sobie sprawę.
Generuje sensowny kod i mam przykładowy pusty szkielet aplikacji. Myślę że zacznę oddzielny wątek na ten temat. A przykładowa większa aplikacja? https://github.com/grzegorz-kraszewski/morsconv, temat może niezbyt interesujący dla większości tu zgromadzonych, ale wszystko to, co ten program potrafi, ładnie się kompiluje do niecałych 9 kB exe. A pisało mi się go naprawdę przyjemniej i szybciej, niż w C (pierwsze wersje były w C, więc mam porównanie). Mimo tego, że to tylko C++99, pozbawione w dodatku wyjątków i dynamic casta.
2
[#46] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Krashan, post #45

Myślę że zacznę oddzielny wątek na ten temat.

To bardzo dobry pomysł.
[#47] Re: [C] Jak wydajnie zamienić liczbę na własny font bitmapowy?

@Krashan, post #44

Przepraszam Krashan, za mocno odpisałem. Przemieśmy dyskusję o C++ do oddzielnego wątku.
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem