Question

Supposons que je programme en Java, en Python ou en C ++ pour un problème simple, qui pourrait consister à construire un serveur d’écho TCP / UDP ou à calculer des facteurs. Dois-je me préoccuper des détails de l’architecture, c’est-à-dire s’il s’agit de 32 ou de 64 bits?

IMHO, à moins que je ne programme quelque chose à faire avec des fichiers de bas niveau, je n'ai pas à me soucier de savoir si c'est du 32 ou du 64 bits. Où vais-je mal? Ou est-ce que j'ai raison ???

Était-ce utile?

La solution

correct dans la plupart des circonstances

Le compilateur runtime / language / résumera ces détails à moins que vous ne traitiez directement avec des tailles de mot ou des valeurs binaires de bas niveau.

Même l'ordre des octets est extrait par la pile de cartes réseau / réseau du noyau. Il est traduit pour vous. Lors de la programmation de sockets en C, vous devez parfois gérer l'ordre des octets pour le réseau lors de l'envoi de données ... mais cela ne concerne pas les différences de 32 ou 64 bits.

Lorsque vous manipulez des blobs de données binaires, les mapper d’une architecture à l’autre (comme une superposition à une structure C par exemple) peut poser des problèmes, comme d’autres l'ont déjà mentionné, mais c’est pourquoi nous développons des protocoles indépendants de l’architecture etc.

En réalité, des éléments tels que Java s'exécutent sur une machine virtuelle, ce qui soustrait la machine à une autre étape!

En savoir plus sur l'ensemble d'instructions de l'architecture et sur la manière dont la syntaxe est compilée peut vous aider à comprendre la plate-forme et à écrire un code plus propre et plus strict. Je sais que je grimace à un vieux code C après avoir étudié les compilateurs!

Autres conseils

Savoir comment les choses fonctionnent, que ce soit le fonctionnement de la machine virtuelle et celle de votre plate-forme, ou la transformation de certaines constructions C ++ en assembleur, fera de vous un meilleur programmeur, car vous comprendrez pourquoi il convient de procéder. comme ils sont.

Vous devez comprendre des éléments tels que la mémoire pour savoir ce que sont les échecs de mémoire cache et pourquoi cela pourrait affecter votre programme. Vous devez savoir comment certaines choses sont mises en œuvre, même si vous n’utilisez qu’une interface ou un moyen très sophistiqué d’y accéder, sachant que son fonctionnement vous permettra de le faire de la meilleure façon possible.

Pour le travail par paquets, vous devez comprendre comment les données sont stockées sur les plates-formes et en quoi l'envoi de celles-ci sur le réseau vers une plate-forme différente peut modifier le mode de lecture des données (endian-ness).

Votre compilateur tirera le meilleur parti de la plate-forme sur laquelle vous compilez. Aussi longtemps que vous respectez les normes et le code, vous pouvez ignorer la plupart des choses et présumer que le compilateur va extraire ce qui est le mieux.

Bref, non. Vous n'avez pas besoin de connaître le niveau bas, mais savoir que ne fait jamais de mal .

La dernière fois que j'ai jeté un œil à la spécification du langage Java, elle contenait un ridicule sur le principe de la boxe sur les entiers.

Integer a = 100;
Integer b = 100;

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

Cela est garanti pour imprimer true.

Integer a = 300;
Integer b = 300;

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

L'impression n'est pas garantie <=>. Cela dépend du temps d'exécution. La spécification l'a laissé complètement ouverte. C'est parce que boxer un int compris entre -128 et 127 renvoie & "Interned &"; objets (de la même manière que les littéraux de chaîne sont internés), mais le développeur du langage d’exécution est invité à augmenter cette limite s’il le souhaite.

Personnellement, je considère cela comme une décision insensée et j'espère qu'ils l'ont corrigé depuis (écrire une fois, courir n'importe où?)

Vous devez parfois vous donner la peine.

Vous pouvez être surpris lorsque ces détails de bas niveau surgissent et vous mordent. Par exemple, Java normalisé double est de 64 bits. Cependant, la machine virtuelle Java Linux utilise la & Quot; précision étendue & Quot; mode, lorsque le double est 80 bits tant qu'il est dans le registre de la CPU. Cela signifie que le code suivant peut échouer:

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

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

assert( y == x );

Tout simplement parce que y est forcé à sortir du registre en mémoire et tronqué de 80 à 64 bits.

In Java and Python, architecture details are abstracted away so that it is in fact more or less impossible to write architecture-dependant code.

With C++, this is an entirely different matter - you can certainly write code that does not depend on architecture details, but you have be careful to avoid pitfalls, specifically concerning basic data types that are are architecture-dependant, such as int.

As long as you do things correctly, you almost never need to know for most languages. On many, you never need to know, as the language behavior doesn't vary (Java, for example, specifies the runtime behavior precisely).

In C++ and C, doing things correctly includes not making assumptions about int. Don't put pointers in int, and when you're doing anything with memory sizes or addresses use size_t and ptrdiff_t. Don't count on the size of data types: int must be at least 16 bits, almost always is 32, and may be 64 on some architectures. Don't assume that floating-point arithmetic will be done in exactly the same way on different machines (the IEEE standards have some leeway in them).

Pretty much all OSes that support networking will give you some way to deal with possible endianness problems. Use them. Use language facilities like isalpha() to classify characters, rather than arithmetic operations on characters (which might be something weird like EBCDIC). (Of course, it's now more usual to use wchar_t as character type, and use Unicode internally.)

If you are programming in Python or in Java, the interpreter and the virtual machine respectively abstract this layer of the architecture. You then need not to worry if it's running on a 32 or 64 bits architecture.

The same cannot be said for C++, in which you'll have to ask yourself sometimes if you are running on a 32 or 64 bits machine

You will need to care about "endian-ness" only if you send and receive raw C structs over the wire like

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

However this is not a recommended practice.

It's recommended that you define a protocol between the parties such it doesn't matter the parties' machine architectures.

In C++, you have to be very careful if you want to write code that works indifferently on 32 or 64 bits. Many people wrongly assume that int can store a pointer, for example.

With java and .net you don't really have to bother with it unless you are doing very low level stuff like twiddling bits. If you are using c, c++, fortran you might get by but I would actually recommend using things like "stdint.h" where you use definitive declares like uint64_t and uint32_t so as to be explicit. Also, you will need to build with particularly libraries depending on how you are linking, for example a 64 bit system might use gcc in a default 64 bit compile mode.

A 32 bit machine will allow you to have a maximum of 4 GB of addressable virtual memory. (In practice, it's even less than that, usually 2 GB or 3 GB depending on the OS and various linker options.) On a 64 bit machine, you can have a HUGE virtual address space (in any practical sense, limited only by disk) and a pretty damn big RAM.

So if you are expecting 6GB data sets for some computation (let's say something that needs incoherent access and can't just be streamed a bit at a time), on a 64 bit architecture you could just read it into RAM and do your stuff, whereas on a 32 bit architecture you need a fundamentally different way to approach it, since you simply do not have the option of keeping the entire data set resident.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top