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

@mateusz_s, post #29

Jak dostęp przez składowe RGB w strukturze jest za wolny, to zawsze możesz zrobić taki manewr:

typedef union _tPixel {
  struct {
    UBYTE Pad;
    UBYTE R;
    UBYTE G;
    UBYTE B;
  };
  ULONG Value; 
} tPixel;


dzięki temu możesz zarówno ustawiać/czytać wartość pixela używając pól r/g/b, a także ustawić/odczytać wszystko hurtem korzystając z pola Value, które "nachodzi" na rgb.

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

@teh_KaiN, post #31

Hej, według mnie to nieco niewłaściwe wykorzystanie unii w języku C.

Myślę, że lepiej jest zastosować zwyczajne kopiowanie struktury:

typedef struct _RGB { UBYTE Alpha, Red, Green, Blue; } RGB;

RGB data[5], yellow = { 0xff, 0xff, 0xff, 0x00 };
RGB *dest, *src = &data[0];

*dest++ = *src;
*dest++ = yellow;


Ostatnia aktualizacja: 12.03.2021 10:11:45 przez Hexmage960
[#33] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Artur Jarosik, post #30

Dzięki, zrobię jak mówisz.. przez całą noc robiła się wersja na tym msys2.. w sensie ze ściągnąłem na Windows msys2 i tam zbudowałem cała dystrybucje.. Czyli wynik będzie inny niż jak to zrobie na tym windows linux subsystem.
[#34] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@teh_KaiN, post #31

Testowałem wariant z Union ale coś się knociło na ekranie,
Ale może coś źle zapisałem, późno już było, sprawdzę jeszcze raz potem..
[#35] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #34

Hej, a spróbowałeś mojego sposobu? Bo unia w tym przypadku jest nieco kłopotliwa - unia nie gwarantuje że te struktury się pokrywają tam gdzie trzeba.
[#36] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #35

Unia powoduje, że elementy są wyrównane w pamięci, czyli:

- elementy składowe zaczynają się w tym samym miejscu - w moim przykładzie adres struktury anonimowej i pola Value jest ten sam
- rozmiar unii jest rozmiarem najdłuższego składowego pola - w moim przykładzie będą to 32 bity.

Inaczej nie byłoby sensu posiadania tego typu konstrukcji w języku C.

Jedyne na co trzeba zwrócić uwagę to to czy Pad ma być z przodu czy z tyłu. Struktura w C umieszcza pola w kolejności zawsze zgodnej z deklaracją. 8-bitowa zmienna nie ma dodatkowych ograniczeń co do wyrównań na 68k jak i x86, więc powinno działać. Najłatwiej sprawdzić czy coś się rozsypuje sprawdzając sizeof typu - powinien być 4.
[#37] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@teh_KaiN, post #36

Inaczej nie byłoby sensu posiadania tego typu konstrukcji w języku C.

Unia istnieje po to by trzymać wiele różnych typów pod jednym obiektem. Rozmiar unii to zawsze jest rozmiar największego elementu w unii, więc jej sens to przede wszystkim zaoszczędzenie miejsca.

Zauważ, że gdyby dajmy na to unia miała tylko R, G i B:

union
{
	struct { UBYTE r, g, b; } rgb;
	ULONG value;
};

To zapis w value w kontekście zapisu do rgb jest problematyczne. "Ogon" wyląduje poza rgb.

Innymi słowy według mnie nie powinno się w taki sposób z unii korzystać.
[#38] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #37

Dlatego przyklad podany wczesniej nie ma "gdyby". Wiec nie ma co dywagowac.
[#39] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #37

przeciez dał pad byte z przodu
[#40] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@michal_zukowski, post #39

Dobrze, nie będę się dalej spierał - ale myślę, że mam rację. Bo to taki przykład - unia może mieć elementy po różne liczby bajtów i te elementy generalnie się wykluczają.

Dosuwanie za pomocą padów przecież nie przyda się np. gdy jedna składowa unii ma 4 bajty, a druga 8 bajtów.

Jeżeli korzystamy z unii to tylko jednocześnie z jednej jej składowej.
[#41] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #40

Jak sie nie przyda? Przeciez okresla wlasnie wskazuje gdzie dane wyladuja.
Wiec poczytaj nie gdybaj.
Jak ktos umie uzyc to da rade.
[#42] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@stefkos, post #41

Ja wiem jak korzystać z unii i tutaj zapaliła mi się "lampka ostrzegawcza".

Podam jeszcze inny przykład:

Załóżmy, że mamy jakiś obiekt z jednym atrybutem, przy czym ten atrybut może mieć kilka rodzajów:

union attrib
{
	UWORD cost;
	ULONG weight;
};

Zapis w cost celem zapisu danej w weight i na odwrót jest problematyczny.

Unii można użyć np. tak:

union attrib *attr;

enum
{
	COST,
	WEIGHT
};

switch (type)
{
	case COST: printf("Cena samochodu: %d\n", attr->cost); break;
	case WEIGHT: printf("Waga samochodu: %ld\n", attr->weight); break;
}

Być może w przykładzie Teh_KaiNa rozmiar składowych unii jest ten sam, ale raczej nie preferowałbym takiego sposobu.

Ostatnia aktualizacja: 12.03.2021 15:07:42 przez Hexmage960
[#43] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #35

też sprawdze ale potem, bo dopiero wieczorkiem przysiądę
[#44] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #37

Zapis w postaci UNION czyli strukt RGBA + integer też działa szybko, pod warunkiem
że piksele zapisujesz do integera poprzez R <<24 | G <<16| B << 8 | 0
bo wpisywanie bezpośrednio do elementów struktury .r = 255 itp zwalnia

natomiast nie zauważyłem różnicy przy odczytywaniu czy to z elementow struktury .r czy poprzez przesuniecie bitowe
[#45] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #42

Unie mogą mieć oba zastosowania, albo do przechowywania roznych rozlacznych danych i tutaj padding zwykle nie ma znaczenia, albo celem dostepu do elementów struktury i jednoczesnie do calosci jako np wartosci rejestru sprzetowego (ktory moze miec wymuszony dostep konkretnym rozmiarem bitowym) i tutaj padding i alignment elementow jest kluczowy.
[#46] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@orila, post #45

Zgodziłbym się z tym, gdyby operacja przypisania była możliwa:

union Color
{
    struct RGB { UBYTE a, r, g, b; } rgb;
    ULONG val;
};

union Color color = 0x01020304;

Co jak unia ma trzy lub więcej składowych?

Jeżeli chcemy osiągnąć efekt szybkiego zapisu 32-bitowego z zachowaniem cech struktury, bezpieczniej jest skorzystać z kopiowania struktury i zostawić kompilatorowi optymalizację:

struct RGB *mem, value = *mem++;

Sprawdziłem i pod VC++ przerabia to na dwa polecenia asemblera na 32-bitowym słowie (DWORD) - jeden odczytuje do rejestru, drugi zapisuje.

W przypadku gdy zrzutujemy na wskaźnik do ULONG - uzyskamy coś podobnego jak kopiowanie struktury, ale jest mniej bezpieczne. W przypadku kopiowania struktury RGB, mamy pewność, że dane zostaną skopiowane właściwie niezależnie od rozmiaru struktury.

Możemy też trzymać piksele w ULONG i porobić makra Red(c), Green(c), Blue(c), Alpha(c), jeżeli znamy format pikseli, ale to chyba mniej wygodne.

Ostatnia aktualizacja: 12.03.2021 21:03:27 przez Hexmage960
[#47] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #46

Operacja przypisania jest mozliwa przez dowolny element unii, czyli np. Color.val, reinterpret cast nie jest w niczym bezpieczniejszy od jawnego wskazania elementu unii; obie operacje przekladaja sie realnie na memcpy obszaru o rozmiarze wskazanych danych; i tutaj bezpieczniej jest uzyc unii bo wybierajac element jednoczesnie wskazujemy rozmiar przez rozmiar elementu, natomiast wskazujac strukture mamy ryzyko ze rozmiar bedzie zalezal od upakowania i wyrownania ktory w srodowiskach np 32-bit jest defaultowo 4B.
Aby konwertowac przez unie nalezy oczywiscie pamietac aby upakowanie zawsze stosowac 1B. Dobrze jest tez zadbac aby alignment w pamieci byl dostosowany do alignmentu sprzetu, aby uniknac ewentualnych strat wydajnosci przy dostepie. Na systemach Sun pod kontrola SunOS nie zachowanie alignmentu skutkuje Bus Error, kiedy ten sam kod pod Linuxem działa ale conajmniej z utrata wydajnosci. W druga stronę zadbanie o alignment choc kosztem pamieci powoduje zysk wydajnosci i stabilnosci na wszystkich targetach.
Unia moze miec dowolnie duzo skladowych np.:
8xBYTE;
4xWORD;
2xDWORD;
1xLONGLONG;
W przypadku dostepu do sprzetu to nie zostawia sie kompilatorowi optymalizacji, bo sprzet moze wymagac konkretnego sposobu dostepu.


Ostatnia aktualizacja: 12.03.2021 21:43:40 przez orila
[#48] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@orila, post #47

OK, unia może mieć nawet kilka składowych o identycznych typach, wskaźniki albo zagnieżdżone struktury.

Przyszedł mi dziś do głowy przykład: Unia przechowuje dokładnie jedną figurę.

Te struktury są niekompatybilne i nadal uważam, że w unii można korzystać tylko z jednej składowej równocześnie.

Co do zapisu w rejestrach sprzętowych to OK, ale podejrzewam że i tutaj składowe się wykluczają. Jeśli mają jakieś części wspólne (np. właśnie typ zawartości unii) to i tak wyprowadzamy je poza unię.

union Figura
{
	struct Prostokat { int a, b; } *p;
	struct Trojkat { int a, h; } *t;
	struct Okrag { int r; } *o;
};

long pole(int typ, union Figura *f)
{
	if (typ == PROSTOKAT)
		return(f->p->a * f->p->b);
	else if (typ == TROJKAT)
		return(f->t->a * f->t->h * 0.5);
	else if (typ == OKRAG)
		return(PI * f->o->r * f->o->r);
	return 0;
}


Ostatnia aktualizacja: 12.03.2021 21:57:33 przez Hexmage960
[#49] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Hexmage960, post #48

Tak jak pisalem unia ma 2 zastosowania, albo do konwersji/przenoszenia danych na poziom sprzetowy albo do przechowywania niezaleznych danych. Nie widze sensu mieszania tego.
[#50] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@orila, post #49

OK, zgoda. Rzeczywiście zetknąłem się całkiem niedawno z taką unią o nazwie REGS.

http://www.delorie.com/djgpp/doc/libc/libc_486.html

I wygląda na to, że masz rację co do takiego zastosowania unii. Ciekawym jak to się przekłada na format pikseli, ale pewnie dokładnie w taki sam sposób (4 bajty/1 długie słowo).

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

@Hexmage960, post #48

Jesli sprzętowo mamy tak ze 2 sasiadujace 32bit rejestry przechowuja 64bit wartosc ktora sklada sie z fragmentow logicznych to unia 3 elementow: 1x longlong, struct{2x long}, struct{bitmap} pozwoli na optymalne kopiowanie calosci przez longlong, jednoczesnie na odczyt/zapis do sprzetu przez 2xlong i odczyt/ustawianie konkretnych bitow.

Natomiast struktura np struct{ int type; union {...}}
sluzy np. do przekazywania w unii roznych niezaleznych danych rozroznianych polem type, co pozwala na reuzycie jednego obszaru pamieci do przekazanie przez jeden interface prawie dowolnych danych.
[#52] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Artur Jarosik, post #30

@Artur Jarosik

hej, zainstalowałem sobie ten Windows Linux Subsystem.. ale czy miałeś na myśli żeby to tam zbudować
instalke dla Windowsa z plików Bebbo, czy używać tych plików które on stworzył dla linuksa?
[#53] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #52

Możesz użyć prekompilowane https://franke.ms/download/amiga-gcc.tgz
[#54] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@Artur Jarosik, post #53

@Artur Jarosik,

Artur, generalnie udało mi się zbudować tą dystrybucje pod Windows Linux Subsystem,
nawet wersje dla Windows, tylko że obu przypadkach0 - dostaje pliki których nie mogę otworzyć ani na Windows ani Linuxie, tj. te pliki m68k-amigaos-gcc

w tym linku co podesłałeś to co to są za pliki? Pod Windowsa? nie mogę też ich otworzyć.
Wiesz o co tu chodzi? Ja nigdy nie zajmowałem się robieniem takiego buildu. Więc nie ogarniam tego do końca.
[#55] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #54

@Artur Jarosik,

ok, już nie istotne.. skompilowam pod linuchem i efekt taki sam..
[#56] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@mateusz_s, post #55

instalowalem dzisiaj:

uname -a
Linux BTN2243 4.4.0-18362-Microsoft #1049-Microsoft Thu Aug 14 12:01:00 PST 2020 x86_64 x86_64 x86_64 GNU/Linux

sudo apt install make wget git gcc g++ lhasa libgmp-dev libmpfr-dev libmpc-dev flex bison gettext texinfo ncurses-dev autoconf rsync
git clone https://github.com/bebbo/amiga-gcc
cd amiga-gcc
make update
make all
sudo chmod 777 opt
export PATH="/opt/amiga/bin:$PATH"
[#57] Re: [C, GCC] Zupełnie inna wydajność między typem int a LONG ?? WTF?

@michal_zukowski, post #56

@michal_zukowski, coś Ci podesłałem na PM
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