Typy zmiennych a ich reprezentacja w pamięci.

Odpowiedz Nowy wątek
2016-02-01 18:43
Wybitny Samiec
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ą?

Pozostało 580 znaków

2016-02-01 19:14
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 (:

edytowany 2x, ostatnio: stryku, 2016-02-01 19:22
Pokaż pozostałe 9 komentarzy
FPU dziś jest częścią procesora, dawniej było osobnym elemntem. Procesory x86 dawniej też nie miały zintegrowanych FPU. - kaczus 2016-02-02 10:20
@Endrju Jednostki operacji wektorowych SSE/AVX (oznaczane jako VPU) są osobnymi jednostkami w procesorze, podobnie jak FPU. Jest kilka FPU i kilka jednostek VPU (obsługującej SSE/AVX/MMX itp.) zwykle po jednej na rdzeń, ale w pewnych procesorach wcale nie takich starych bywało po kilka FPU na rdzeń. Np. chyba port 0 i 1 w Haswell mają swoje własne FPU. Jedynie jednostka do fdiv jest jedna na rdzeń i jest wydzielona. - Krolik 2016-02-02 12:32
Totalne bzdury! Ale widzę, że wiecie lepiej i nie macie zamiaru słuchać, więc i ja nie mam zamiaru Was wyprowadzać z tych bzdur. :-D Przypominam tylko, że jest 2016 rok. - Endrju 2016-02-02 12:52
lepiej to wyjaśnić niż urywacie dyskusje - karolinaa 2016-02-02 13:00
@Endrju, ja za to widzę, że ty jak zwykle wiesz wszystko najlepiej, ale nie raczysz wytłumaczyć, tylko będziesz każdemu krzyczał, że źle i nie ma racji :D No i twoje ulubione EOT po tym jak już na kogoś naskoczysz. - some_ONE 2016-02-02 14:35

Pozostało 580 znaków

2016-02-01 19:38
Wybitny Samiec
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 ?

Pozostało 580 znaków

2016-02-02 09:36
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ą)


Ogólnie na prace domowe mam stawki zaporowe. Czasem coś o programowaniu znajdzie się na mojej stronie

Pozostało 580 znaków

2016-02-02 11:59
0


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


Pozostało 580 znaków

2016-02-02 14:20
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).

Pozostało 580 znaków

2016-02-02 20:00
chalon
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.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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