2009-06-25 15 views
6

Załóżmy, że programuję w Javie, Pythonie lub C++ dla prostego problemu, może być zbudowanie serwera echo TCP/UDP lub obliczenie silni. Czy muszę zawracać sobie głowę szczegółami architektury, tj. Czy jest to 32 czy 64-bit?Czy trzeba znać architekturę maszyny, aby napisać kod?

IMHO, chyba jestem programowania coś z dość niskiego poziomu rzeczy, wtedy nie muszę się przejmować, jeśli jego 32 lub 64 bit. Gdzie się mylę? Czy mam rację?

+0

Mate czy rozumiesz nawet języki takie jak Java? Działa prawie niezmodyfikowany na wszystkich obsługiwanych platformach bez żadnych zmian programu. –

+0

Porównanie Javy z C++ pod względem niezależności platformy pokazuje brak zrozumienia zalet i wad wymienionych języków/platform. –

+0

wymienione języki to tylko przykłady! Nie porównuję ani nie krytykuję! – g06lin

Odpowiedz

15

prawidłowe dla większości przypadków

Środowisko wykonawcze/language/kompilator będzie abstrakcyjne te dane, chyba że masz do czynienia bezpośrednio z wielkości tekstu lub binarny na niskim poziomie.

Nawet bajt jest pobierany przez stos NIC/Network w kernelu. To jest przetłumaczone dla ciebie. Podczas programowania gniazd w C, czasami musisz radzić sobie z porządkowaniem bajtów dla sieci podczas wysyłania danych ... ale to nie dotyczy różnic 32 lub 64-bitowych.

Gdy mamy do czynienia z obiektami blotującymi dane binarne, mapowanie ich z jednej architektury do drugiej (na przykład nakładanie się na strukturę C) może powodować problemy, o których wspomnieli inni, ale dlatego opracowujemy niezależne od architektury protokoły oparte na znakach i tak dalej.

Rzeczywiście takie rzeczy jak Java działają w maszynie wirtualnej, która abstrahuje od maszyny kolejny krok!

Znając trochę o zestaw instrukcji architektury i jak składnia jest kompilowany na które mogą pomóc zrozumieć platformę i napisać czystsze, mocniej kodu. Wiem, że grymasuję po starym kodzie C po przestudiowaniu kompilatorów!

+2

Byłem błogo nieświadomy sprzętu procesora przez wiele lat. Nie wiedziałem ani nie potrzebowałem tego wiedzieć, odkąd ostatnio pisałem kontrolerów czasu rzeczywistego dla broni wojskowej. –

+1

"Kontrolery czasu rzeczywistego dla broni wojskowej" - Awesome! –

0

Trzeba dbać o „endian-ness” tylko wtedy, gdy wysyłać i odbierać konstrukcjom surowy C nad drutu jak

 
ret = send(socket, &myStruct, sizeof(myStruct)); 

Jednak nie jest to zalecana praktyka.

Zaleca się zdefiniowanie protokołu między stronami, tak aby nieistotne było to, że architektura komputerów stron jest bez znaczenia.

+0

Nie, to o wiele gorsze. Musisz znać endianię, jeśli czytasz lub zapisujesz dowolne dane binarne do plików, i nie ma znaczenia, czy jest w strukturach, czy nie. –

+0

Jeśli piszesz do plików binarnych, już uzgodniono protokół, którego obie strony będą używać do komunikowania się ze sobą. Protokół jest formatem pliku. – Reginaldo

0

W C++, trzeba być bardzo ostrożnym, jeśli chcesz napisać kod, który działa obojętnie na 32 lub 64 bitów. Wiele osób błędnie zakłada, że ​​na przykład int może przechowywać wskaźnik.

+0

Nigdy nie miałem z tym problemów. Przez lata miałem problemy z ludźmi, którzy uważali, że int jest taki sam jak size_t. –

+1

Czy domniemanie szerokości typu (gdy jest to niedopasowane) nie jest po prostu kiepską praktyką programowania? : P –

+1

O tak, jest. Jest to jednak powszechna praktyka programistyczna. Po raz pierwszy zauważyłem to, gdy uczyłem z podręcznika, który sugerował wypróbowanie "printf (" Rozmiar int to% d \ n ", sizeof (int));" a uczeń dostał zero wydrukowane - na system big-endian, gdzie int było 16 bitów i size_t 32. –

15

Wiedząc, jak to działa, tak jak działa wirtualna maszyna i jak działa na twojej platformie, lub jak pewne konstrukty C++ są przekształcane w zespół zawsze będziesz lepszym programistą, ponieważ zrozumiesz, dlaczego rzeczy powinny być zrobione tak, jak są.

Musisz zrozumieć takie rzeczy jak pamięć, aby dowiedzieć się, jakie są luki w pamięci podręcznej i dlaczego te mogą wpływać na twój program. Powinieneś wiedzieć, w jaki sposób pewne rzeczy są wdrażane, nawet jeśli możesz użyć tylko interfejsu lub wysokiego poziomu, aby się do niego dostać, wiedząc, jak to działa, upewnij się, że robisz to w najlepszy sposób.

W przypadku pracy pakietowej należy zrozumieć, w jaki sposób dane są przechowywane na platformach oraz w jaki sposób ich wysyłanie przez sieć do innej platformy może zmienić sposób odczytu danych (endian-ness).

Twój kompilator najlepiej wykorzysta platformę, na której się kompilujesz, więc dopóki będziesz trzymać się norm i kodu, możesz zignorować większość rzeczy i założyć, że kompilator rozwiąże to, co najlepsze.

Krótko mówiąc, nie. Nie musisz znać rzeczy na niskim poziomie, ale to nigdy nie boli wiedzieć,.

+0

Całkowicie się z Tobą zgadzam – g06lin

+1

Ostatni kawałek jest bardzo dobrze napisany: "nigdy nie boli wiedzieć" – BCS

1

Jeśli programujesz w języku Python lub w Javie, interpreter i maszyna wirtualna odpowiednio abstrakują tę warstwę architektury. Nie musisz się wtedy martwić, jeśli działa na architekturze 32- lub 64-bitowej.

Tego samego nie można powiedzieć o C++, w której trzeba zadać sobie czasami, jeśli jest uruchomiony na komputerze z 32 lub 64 bity

3

W Java i Python, szczegóły architektury są wydobywane z dala tak, że jest w rzeczywistości mniej lub bardziej niemożliwym do napisania kodu zależnego od architektury.

Z C++ to zupełnie inna sprawa - na pewno można napisać kod, który nie zależy od szczegółów architektury, ale trzeba uważać, aby uniknąć pułapek, w szczególności dotyczących podstawowych typów danych, które są zależne od architektury, takich jak int.

6

Czasami musisz się martwić.

Możesz być zaskoczony, gdy te szczegóły na niskim poziomie nagle wyskoczą i ugryzą cię. Na przykład Java standaryzowała double na 64-bitową. Jednak JVM dla systemu Linux używa trybu "rozszerzonej precyzji", gdy podwójny jest 80-bitowy, tak długo, jak jest w rejestrze procesora. Oznacza to, że po kod może ustała

double x = fun1(); 
double y = x; 

System.out.println(fun2(x)); 

assert(y == x); 

prostu dlatego, że Y jest wypychany z rejestru do pamięci i odcięto od 80 do 64 bitów.

+1

Czy to nie oznacza, że ​​JVM Linux nie jest standardem? IIRC, Java definiuje Operacje zmiennoprzecinkowe z bardzo dużą szczegółowością –

+1

Ten przykład demonstruje coś innego - implementator środowiska uruchomieniowego języka musi poprawnie zrozumieć definicję języka - jest to po prostu zepsute, ponieważ żaden programista Java nie powinien tego tolerować: –

+2

Tak, to jest błąd: Zostało to zgłoszone jako błąd w GNU Java, ale zostało zignorowane: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16122 –

2

Dopóki wszystko robisz poprawnie, prawie nigdy nie musisz znać większości języków. W wielu przypadkach nigdy nie musisz tego wiedzieć, ponieważ zachowanie języka nie jest różne (na przykład Java określa dokładnie działanie środowiska wykonawczego).

W językach C++ i C wykonywanie czynności poprawnie obejmuje nieprzyjęcie założeń dotyczących int. Nie umieszczaj wskaźników w int, a gdy robisz cokolwiek z rozmiarami lub adresami pamięci, użyj size_t i ptrdiff_t. Nie licz na wielkość typów danych: int musi wynosić co najmniej 16 bitów, prawie zawsze wynosi 32, a na niektórych architekturach może wynosić 64. Nie zakładaj, że arytmetyka zmiennoprzecinkowa będzie wykonywana w dokładnie taki sam sposób na różnych maszynach (standardy IEEE mają w sobie pewną swobodę).

Prawie wszystkie systemy operacyjne obsługujące tworzenie sieci umożliwiają rozwiązanie problemów związanych z endogenicznością. Użyj ich. Użyj obiektów językowych, takich jak isalpha(), aby klasyfikować znaki, a nie operacje arytmetyczne na znakach (co może być dziwne jak EBCDIC). (Oczywiście, teraz bardziej powszechnie jest używać wchar_t jako typu znaku i wewnętrznie używać Unicode.)

6

Ostatni raz gdy spojrzałem na specyfikację języka Java, zawierało absurdalne pojęcie w sekcji o boksie całkowitym.

Integer a = 100; 
Integer b = 100; 

System.out.println(a == b); 

To gwarantuje wydruk true.

Integer a = 300; 
Integer b = 300; 

System.out.println(a == b); 

To nie gwarantuje wydrukowania true. To zależy od środowiska wykonawczego. Spec pozostawił to całkowicie otwarte. Dzieje się tak dlatego, że boksowanie int pomiędzy -128 a 127 zwraca "internowane" obiekty (analogiczne do sposobu, w jaki literały łańcuchowe są internowane), ale implementator języka jest zachęcany do podniesienia tego limitu, jeśli sobie tego życzy.

Osobiście uważa, że ​​jak szalony decyzji i mam nadzieję, że już ustalone to od (napisz raz, uruchom wszędzie?)

+0

znalazłeś więcej głupiej decyzji projektowej Javy – GogaRieger

+0

interesujących ... Patrząc na szczegóły "internowanych" obiektów! Na maszynie JVM 1.6.0_14 na 32-bitowym systemie Linux w wersji 32-bitowej, otrzymuję prawdę tak długo, jak długo & b są <128. – g06lin

+0

Mam rozmiar zakresu w prawo, ale jest on podpisany (od -128 do 127) - patrz http: //java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7 –

0

z Java i .NET naprawdę nie trzeba męczyć się z nim chyba robisz rzeczy o bardzo niskim poziomie, takie jak bity twiddling. Jeśli używasz c, C++, fortran, możesz przejść przez, ale naprawdę polecam używanie takich rzeczy jak "stdint.h", gdzie używasz ostatecznych deklaracji takich jak uint64_t i uint32_t, aby były wyraźne. Ponadto będziesz musiał budować ze szczególnie bibliotekami w zależności od tego, jak się łączyć, na przykład 64-bitowy system może używać gcc w domyślnym 64-bitowym trybie kompilacji.

0

Maszyna 32-bitowa pozwala na maksymalnie 4 GB adresowalnej pamięci wirtualnej. (W praktyce jest to nawet mniej, zazwyczaj 2 GB lub 3 GB w zależności od systemu operacyjnego i różnych opcji linkera). Na maszynie 64-bitowej można mieć OGROMNĄ wirtualną przestrzeń adresową (w praktycznie praktycznym sensie, ograniczoną tylko przez dysk) i całkiem cholernie duża pamięć RAM.

Więc jeśli spodziewasz się zestawów danych 6GB dla niektórych obliczeń (powiedzmy coś, co wymaga niespójnego dostępu i nie może być po prostu przesyłane trochę na raz), na 64-bitowej architekturze można po prostu odczytać go do pamięci RAM i rób swoje rzeczy, podczas gdy w architekturze 32-bitowej potrzebujesz zupełnie innego sposobu podejścia do niej, ponieważ po prostu nie masz możliwości utrzymania całego zbioru danych rezydentem.

Powiązane problemy