Typy zmiennych a ich reprezentacja w pamięci.

1

Witam
Chciałbym dowiedzieć się czy dobrze rozumiem pewne kwestie dotyczące
typów zmiennych, które używamy programując np w C++ jak są reprezentowane
w pamięci etc.
Ostatnio wykładowca powiedział, że nie ważne jakiego typu zmiennej użyjemy
to i tak słowo ma 32/64 bity w zależności od architektury i w taki sposób będzie
przetwarzane przez procesor (tak to zrozumialem).
Czyli np char zajmuje 1bajt ale i tak w rejestrze
będzie 4/8 bajtów?

Z tego co wiem w pamięci fizycznej (RAM) przechowywane są bajty danych
i do każdego z nich odwołujemy się za pomocą adresu. Załóżmy że deklaruję zmienna
int(4bajty). Co za to odpowiada, że do tej zmiennej mogę się odwołać za pomocą
jednego adresu? Procesor na podstawie typu zmiennej "wie" ile kolejnych bajtów pobrać z pamięci?

Dlaczego zmienna może mieć rozmiar większy niż 8 bajtów np long double?
Przecież dzisiejsze procesory są 64 bitowe a więc rejestry są 64 bitowe, jak
takie zmienne są przetwarzane,jak się zmieszczą w tych rejestrach?
Jakie mechanizmy za to odpowiadają?

3
Wybitny Samiec napisał(a):

Czyli np char zajmuje 1bajt ale i tak w rejestrze
będzie 4/8 bajtów?

1 bajt zajmuje 1 bajt. Są rejestry o różnych wielkościach, ale np. w x86_64 jak wrzucisz bajt do rejestru al, i potem chcesz wrzucić int64_t do rejestru rax to ten wcześniejszy bajt zostanie nadpisany bo rejestr al wchodzi w skład rejestru rax.
user image

Wybitny Samiec napisał(a):

Z tego co wiem w pamięci fizycznej (RAM) przechowywane są bajty danych
i do każdego z nich odwołujemy się za pomocą adresu. Załóżmy że deklaruję zmienna
int(4bajty). Co za to odpowiada, że do tej zmiennej mogę się odwołać za pomocą
jednego adresu? Procesor na podstawie typu zmiennej "wie" ile kolejnych bajtów pobrać z pamięci?

Procesor tylko wykonuje rozkazy. O tym jaki rozkaz ma być decyduje kompilator. I jak kompilator widzi, że ma pobrać zmienną typu int czyli (załóżmy) cztero-bajtową to tworzy rozkaz, który pobiera zmienną cztero-bajtową. Adres jest jeden ponieważ procesor pobiera cztery bajty, które są obok siebie. Czyli jak ma pobrać cztery bajty z adresu np. 0x40 to pobiera bajty 0x40, 0x41, 0x42 i 0x43 (nie zawsze jest taka kolejność, zależy jaka jest forma zapisu na danej architekturze (big endian, little endian itp. jakbyś chciał poczytać)).

Wybitny Samiec napisał(a):

Dlaczego zmienna może mieć rozmiar większy niż 8 bajtów np long double?
Przecież dzisiejsze procesory są 64 bitowe a więc rejestry są 64 bitowe, jak
takie zmienne są przetwarzane,jak się zmieszczą w tych rejestrach?
Jakie mechanizmy za to odpowiadają?

Istnieje tak zwany koprocesor, jest on odpowiedzialny za operacje na liczbach zmiennoprzecinowych. Na x86 jego rejestry mają 80 bitów

W standardzie jest, §3.9.1 ¶8

There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double. The value representation of floating-point types is implementation-defined. Integral and floating types are collectively called arithmetic types. Specializations of the standard template std::numeric_limits (18.3) shall specify the maximum and minimum values of each arithmetic type for an implementation.

Czyli w skrócie, double ma przynajmniej taką precyzję jak float, a long double ma przynajmniej taką jak double. Nigdzie nie ma napisane co ile ma bitów. Na x86 z reguły float ma 32 bity, double 64, a long double 80, właśnie dzięki tym rejestrom koprocesora.

Niektóre kompilatory dają long double 128 bitów, ale jest to zależne od implementacji. Nie są one wtedy trzymane całe w rejestrach. Jakie mechanizmy za to dokładnie odpowiadają nie wiem (:

0

Istnieje tak zwany koprocesor, jest on odpowiedzialny za operacje na liczbach zmiennoprzecinowych. Na x86 jego rejestry mają 80 bitów

Czyli przesłanie liczby 80 bitowej odbędzie się w kilku cyklach procesora ponieważ magistrala ma 32/64 bity ?

0

Przesyłasz do rejestrów jednostki zmiennoprzecinkowej, a nie do rejestrów procesora. Może byc to też 128 bitów albo 96 (niektóre układy specjalizowane tak mają)

0


tu nasz kolega z forum dużo wyjaśnia na ten temat

0

AFAIK Intel powoli stara się wyplenić 80-bitowe liczby zmiennoprzecinkowe na rzecz tych zgodnych z IEEE, czyli 16-, 32-, 64- i 128-bitowych (a AVX wprowadza wsparcie dla 256- i 512-bitowych).

0
Wybitny Samiec napisał(a):

Istnieje tak zwany koprocesor, jest on odpowiedzialny za operacje na liczbach zmiennoprzecinowych. Na x86 jego rejestry mają 80 bitów

Czyli przesłanie liczby 80 bitowej odbędzie się w kilku cyklach procesora ponieważ magistrala ma 32/64 bity ?

To akurat różnie pójdzie, bo zależnie od położenia w ram, oraz samego stera ram - dual, single itp.

Np. gdy masz typowy ram, znaczy 64 bitwa szyna i transmisja, wtedy te 64 bity = 8 bajtów,
są zwykle czytane w jednym cyklu... co niekoniecznie znaczy w jednym takcie procesora...
ale pod warunkiem że to jest pod adresem modulo 8, znaczy: 0, 8, 16, ...

natomiast gdy ta zmienna siedzi pod adresem niepodzielnym przez 8, np.: 6, 7 albo 143, 516, itp.
to wtedy część siedzi w pierwszej 8-ce, a reszta w drugiej drugiej,
co w sumie daje 16...
no o to wtedy ram musi przesłać 16 bajtów, a nie tylko 8... czyli to dwa razy dłużej wyjdzie, średnio biorąc.

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