[#1] [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?
hej,
i znowu szok.
Czy to możliwe że w GCC typ int to jest coś innego niż LONG?
Wydajność LONG dwa razy większa niż int. ??

Miałem do tej pory bufor dynamiczny typu int za pomocą malloc.
I miałem fps rzędu 25 kl.s.. zmieniłęm tym na ULONG (a potem LONG)
żeby móc przetestować QuickMemCpy.. ale jeszcze jej nie użyłem tylko normalnie WritePixelArray,
nagle wszsytko przyśpieszyło z 25 do prawie 60 fps.. czy to znowu jakiś chochlik Winuae?
[#2] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #1

Wydrukuj sobie za pomocą printf sizeof(int) i sizeof(LONG) to być może się dowiesz, bo możliwe, że dla twojego GCC int ma 64 bity, by tego uniknąć chyba należałoby używać typów jak uint32_t lub przedefinować ULONG i inne na taki, tu widać jawnie rozmiar zmiennej.

Ostatnia aktualizacja: 09.03.2021 18:34:52 przez san_u
[#3] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@san_u, post #2

tyle samo mają, po 4 bajty..
[#4] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #3

a próbowałeś może podejrzeć, co GCC generuje w assemblerze?
[#5] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@san_u, post #4

a jaki parametr dać do gcc zeby zapisał plik asm.. to mogę tu wkleić,
bo mi kod w asemblerze nic nie powie niestety

Ostatnia aktualizacja: 09.03.2021 19:10:59 przez mateusz_s
[#6] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #5

--save-temps
[#7] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #5

nawet jeśli nie znasz assemblera, to wygenerowany plik assemblera daje ci przynajmniej podgląd na ilość instrukcji jaka jest generowana na daną funkcję, kiedyś używałem tego do wyprofilowania kodu na kopiowanie pamięci w VBCC i było widać, że 11 instrukcji, to nie to samo co 3 instrukcje

tak dla przykładu

_memcpy_fast
	movem.l	l87,-(a7)
	move.l	(12+l89,a7),d0
	move.l	(8+l89,a7),a1
	move.l	(4+l89,a7),a0
	lsr.l	#2,d0
	beq	l86
l85
	move.l	(a1)+,(a0)+
	subq.l	#1,d0
	bne	l85
l86
l87	reg
l89	equ	0
	rts


kopiowanie jest pod 185, w zależności od tego jak była opisana pętla i wybranej optymalizacji, w tym miejscu ilość instrukcji się zmieniała

Ostatnia aktualizacja: 09.03.2021 20:11:01 przez san_u
[#8] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #1

Coś nie tak, LONG/ULONG to typedefy o ile pamietam exec/types.h, ewentualnie przegrepuj os-includesy. No i pamietaj, żeby kompilować z -noixemul. Spróbuj sie pobawić tez -mcpu albo -mtune. W sumie juz nie pamietam dokladnie co dawalo speedupa na 68k.
[#9] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@michal_zukowski, post #8

@san_u no tak tylko nie wiem jak wygenerować kod asm z gcc

@michal_zukowski niee no.. wole te ULONGI bo mi wzrosło 2x ponad, kod mam napisany tak ze korzystam ze swoch typedefów więc tylko sobie podmienie
na ULONG i LONG, uzywam -noixemul.. do mcpu i fpu jescze nie doszedłem, testuje każdą zmianę żeby wiedzieć co i jak.. bo jak widać wystarczy "chuchnąć" i dzieją się różne cuda..



Ostatnia aktualizacja: 09.03.2021 20:36:03 przez mateusz_s
[#10] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #9

Chodzilo mi o to ze

https://github.com/deplinenoise/amiga-sdk/blob/master/sdkinclude/exec/types.h

tu widac ze LONG to juz jest typedef na long
typedef long LONG;

pytanie co masz nie tak z intem, może gcc jakies trafione
[#11] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@michal_zukowski, post #10

to się działo przy P96API, teraz przerzuciąłem sobie kod na CGX i mam odwrotny efekt, tj. int jest 2-3x szybszy niż LONG.. nic z tego nie rozumiem.. pewnie kompilator coś miesza
[#12] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@michal_zukowski, post #10

Malo prawdopodobne, ze cos nie tak z gcc. Uzywam tego samego i nie trafilem na podobne problemy (jeszcze).

@Mateusz - jakich konkretnie flag przy kompilacji gcc uzywasz? -O3, -noixemul, cos jeszcze?
Jesli nie uzywasz -mtune ani -march czy mozesz sprobowac dodac -m68020-60 i zobaczyc czy to cokolwiek zmieni (znaczy czy nadal bedzie roznica taka duza pomiedzy int/LONG).
Pisales, ze zmieniales unsigned na signed - czy te roznice w predkosci sa tylko w przypadku kiedy uzywasz long vs int, czy moze na przyklad tylko w przypadku unsigned long vs int?
[#13] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@lef, post #12

@lef

Hej,

Kiedy mam te flagi: -O3 -noixemul -lm -Wall,
wartości kształtują się tak:

ULONG - 30fps
LONG - 70fps
int oraz unsigned int - 171 fps

kiedy daje wszsytko: -O3 -noixemul -lm -Wall -march=68060 -mcpu=68060
-mtune=68060 -mhard-float -68881,
to wartośći są takie:

ULONG - 70fps
LONG - 70fps
int oraz unsigned int - 180 fps

używam dokładnie tego kompilatora, z tej instalki:
https://github.com/bebbo/amiga-gcc/releases/tag/gridone
(zrąbany jakiś??)

Podsyłam Ci kod, jeśli chciałbyś sobie sam sprawdzić:
https://we.tl/t-GmuZ0yJsYh

Ostatnia aktualizacja: 10.03.2021 02:11:09 przez mateusz_s
[#14] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@lef, post #12

Jest różnica, użyłem -save-temps by wygenerować pliki assemblera i zmieniłem:
unsigned int* my_buf_1 = (unsigned int*)malloc(size);

na
ULONG* my_buf_1 = (unsigned int*)malloc(size);


różnice są tutaj, po lewej kod unsigned int:

https://www.diffchecker.com/gi3FDbkt

Ostatnia aktualizacja: 10.03.2021 03:46:09 przez san_u
[#15] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@san_u, post #14

No ciekawe Kurcze, fajna ta stronka, będę sobie porównywał teraz..
[#16] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #15

A patrzyłes gcc2.95 na prawdziwym AmigaOS? A nie kroskompilator?
[#17] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@san_u, post #14

Ciekawe, kompilator nie umie wydedukować, że ta pętla efektywnie inkrementuje tylko wskaźnik:

for(int x = 0; x < APP_requested_width; ++x)
{
my_buf_1[x + y * APP_requested_width] = (unsigned int)fade<<24;
}

L57:
move.l d0,(a0)+
addq.l #1,d1
cmp.l d1,d2
jhi .L57

vs

.L65:
move.l d2,-(sp)
move.l d3,-(sp)
jsr (a3)
add.l a6,d0
lsl.l #2,d0
addq.l #8,sp
move.l d4,(0,a2,d0.l)
addq.l #1,a6
cmp.l a6,d2
jhi .L65

Nie ma się co dziwić, że jest wolniej. Dlaczego? Nie wiem:) Bug w kompilatorze? Druga wersja dla każdej iteracji oblicza przesunięcie (ten jsr to mnożenie, co jest też dziwne że nie wstawił tam mul bezpośrednio)

Ostatnia aktualizacja: 10.03.2021 09:15:15 przez kiero
[#18] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@kiero, post #17

Mam tylko ten jeden kompilator na razie.
Jak widać trzeba będzie przetestować tez jakieś inne.

Na eab jest wątek o tym kompilatorze w ktorym odpisuje Bebbo, można mu to tam podrzucić.

Ostatnia aktualizacja: 10.03.2021 09:28:23 przez mateusz_s
[#19] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #18

Skompiluj pod GCC 2.95 pod AmigaOS i zobacz.

Sciagasz, rozpakowujesz, uruchamiasz skrypt, przenies tylko includy z CGXa (proto i z inline) bo tam są złe
https://aminet.net/package/dev/gcc/ADE
[#20] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@michal_zukowski, post #19

Zerknę potem.. A moze ten cubic ide, bo tam jest też chyba vbcc?
[#21] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #18

@Mateusz_s
@Kiero

Wygląda na to, że kompilator kompiluje w zgodności z procesorem MC68000. Ten procesor nie posiada bezpośredniej instrukcji mnożącej dwa 32-bitowe słowa, stąd wywoływana jest ta funkcja mnożenia.

Widać, że unsigned long traktuje jako 32-bitowe słowo, a unsigned int jako 16-bitowe słowo (mimo, że podaje 4 bajty).

Może warto spróbować skompilować np. z -mc68020, jeżeli nie zależy nam na takiej zgodności? Mam nadzieję, że się nie pomyliłem.

Ostatnia aktualizacja: 10.03.2021 09:47:28 przez Hexmage960
[#22] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #20

Jęsli piszesz cos od podstaw w C to chyba najlepiej zostać na 2.95, Gcc6 jak cos portujesz z innych systemów. Możesz jeszcze sprawdzić SASC i to VBCC, ale nie wiem czy kod będzie lepszy niz z GCC2.95.
[#23] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #21

W tym przypadku model nie ma znaczenia, bo kompilator nie musi wykonywać mnożeń a tylko (tak jak w przypadku "po lewej") inkrementować adres. Po prostu z jakiegoś powodu nie stwierdza tej prostej zależności
[#24] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@kiero, post #23

To moze byc rzeczywiscie blad w kompilatorze (a przynajmniej w tym buildzie, ktorego uzywa Mateusz). Mam te sama wersje, tylko ze skompilowalem sam (https://github.com/bebbo/amiga-gcc, host macos). Moj bez problemu sobie radzi z zastapieniem tej petli przez proste move.l d0, (a0)+. Bez wzgledu na znak i bez wzgledu na wybrana architekture.
[#25] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@kiero, post #17

Nawet na tym krótszym fragmencie widać że optymalizacja jest słaba, zrobiona dla ogólnego przypadku gdzie x może zaczynać się od dowolnej wartości. To też jest słabo zrobione bo wystarczy przed pętlą odjąć D1 od D2 i zaczynamy od zera.

Przy APP_requested_width = 320 pętla L57 potrzebuje 4160 cykli na wykonanie.


Powinno być tak:

move.w #APP_requested_width-1, D1
.loop1
move.l D0, (a0)+
dbra D1, .loop1

Przy APP_requested_width = 320 pętla .loop1 potrzebuje 2880 cykli na wykonanie.

Stała w D1 jest na pewno podzielna przez potęgi dwójki więc można jeszcze pętlę rozwinąć na kilka instrukcji move. Już przy czterech instrukcjach opłaci się użyć movem.

move.l D0, D1
move.l D0, D2
move.l D0, D3
move.l D0, A1
move.l D0, A2
move.l D0, A3
move.l D0, A4

move.w #APP_requested_width/8-1, D5
moveq #32, D4
.loop8
movem.l D0/D1/D2/D3/A1/A2/A3/A4, (a0)
add.l D4, A0
dbra D5, .loop8

Przy APP_requested_width = 320 pętla .loop8 potrzebuje 1120 cykli na wykonanie.

Czyli z 4160 zjechaliśmy na 1120 cykli. Czasy są dla 020/030. Dla .L65 nie chce mi się liczyć ale wiadomo że masakra :)

Nawet jeśli pętla nie jest podzielna to część zaokrągloną do podzielnej robimy movem a ogon dokańczamy pętlą z pojedynczą instrukcją.

Ostatnia aktualizacja: 10.03.2021 10:55:16 przez Kefir_Union
[#26] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@michal_zukowski, post #19

Sciagasz, rozpakowujesz...

Taka mala uwaga przy rozpakowywaniu tego archiwum.
W zadnym wypadku nie uzywac do tego celu VoodooX! Bo sie mozna zdziwic...
Najlepiej uzyc zwyklego Lha.
[#27] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Phibrizzo, post #26

To archiwum ZIP...
[#28] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@michal_zukowski, post #27

Faktycznie. Napisalem z rozpedu bo na Aminecie jeszcze jest nowsza wersja z 2017:
ADE

Edit: tak czy siak nawet ZIPa prosze nie rozpakowywac pod VoodooX. Jest dokladnie ten sam problem. Sprawdzilem.


Ostatnia aktualizacja: 10.03.2021 16:15:36 przez Phibrizzo
[#29] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@lef, post #24

Jak wspomniałem umieściłem opis tego problemu w wątku gcc 6 bebbo na eab-ie i Ktoś odpisał, z wyjaśnieniami:
http://eab.abime.net/showthread.php?t=85474&page=63

Niesamowite jest to, że zrobiłem tak jak napisał - czyli: zmieniałem WIDTH i HEIGHT które były warunkiem w petlach for z INT na CONST UNSIGNED SHORT i z 190 fps skoczyło do 550 fps !! spora różnica.

Jeszcze dodałem te flagi do gcc -funroll-loops -fomit-frame-pointer no i teraz ten unroll zadziałał jak trzeba..

druga rzecz, która też wpływa na wydajność to zastąpienie unsigned int do trzymania koloru na strukturę rgba,
któa skłąda się z 4 pół unsigned char. Tzn. taką strukturą mam w swoim Raycasterowym projekcie. Muszę pozbyć się tej struktury i operować bezpośrednio na unsigned int.. zoabczymy czy po tych zabiegach coś skoczy..

Ostatnia aktualizacja: 12.03.2021 03:18:41 przez mateusz_s
[#30] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #29

Tutaj możesz swój kod porównać pomiędzy gcc 2.95, gcc 3.4 , gcc 4 i najnowszym gcc6 online.
Ostatni gcc6 powinien mieć lepszy wynik dlatego zalecam aktualizację i to najlepiej na Windows Linux Subsystem. Wersja na Msys2 działa wolniej i ma błędy.
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