2009-06-25 6 views
6

Digamos que estoy programando en Java o Python o C++ para un problema simple, podría ser construir un servidor de eco TCP/UDP o un cálculo de factorial. ¿Tengo que preocuparme por los detalles de la arquitectura, es decir, si es de 32 o 64 bits?¿Tendría que conocer la arquitectura de la máquina para escribir el código?

En mi humilde opinión, a menos que esté programando algo para hacer con cosas de bajo nivel, entonces no tengo que molestarme si es de 32 o 64 bits. ¿Dónde estoy equivocado? ¿O estoy en lo cierto?

+0

¿Alguna vez entiende el sentido de idiomas como Java? Prácticamente se ejecuta sin modificaciones en todas las plataformas compatibles sin cambios en el programa. –

+0

La comparación de Java con C++ en términos de independencia de la plataforma muestra una falta de comprensión de los méritos y fallas de los idiomas/plataformas mencionados. –

+0

¡los idiomas mencionados son solo ejemplos! ¡No estoy comparando ni criticando! – g06lin

Respuesta

15

correcta para la mayoría de las circunstancias

El tiempo de ejecución/idioma/compilador abstractos esos detalles a menos que esté tratando directamente con tamaños de texto o binario en un nivel bajo.

Incluso byteorder es abstraído por la pila NIC/Network en el kernel. Está traducido para ti. Al programar tomas en C, a veces tiene que ocuparse del orden de bytes de la red al enviar datos ... pero eso no se aplica a las diferencias de 32 o 64 bits.

Cuando se trata de blobs de datos binarios, asignarlos de una arquitectura a otra (como una superposición a una estructura C por ejemplo) puede causar problemas como otros han mencionado, pero es por eso que desarrollamos protocolos independientes de arquitectura basados ​​en caracteres y así.

De hecho cosas como Java se ejecutan en una máquina virtual que abstrae la máquina otro paso!

Conociendo un bit sobre el conjunto de instrucciones de la arquitectura, y cómo se compila la sintaxis que puede ayudarle a comprender la plataforma y escribir un código más claro y más ajustado. ¡Sé que hago una mueca ante algún antiguo código C después de estudiar compiladores!

+2

Ha sido felizmente ajeno al hardware del procesador durante años y años. No sabía ni necesitaba saber desde la última vez que escribí controladores en tiempo real para armas militares. –

+1

"Controladores en tiempo real para armas militares" - ¡Impresionante! –

0

Usted tendrá que preocuparse por "endian-ness" sólo si usted envía y recibe estructuras prima C sobre el alambre como

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

Sin embargo, esto no es una práctica recomendada.

Se recomienda que defina un protocolo entre las partes, ya que no importa las arquitecturas de máquina de las partes.

+0

No, es mucho peor que eso. También debe saber endianness si lee o escribe datos binarios en archivos, y no importa si está en estructuras o no. –

+0

Si está escribiendo en archivos binarios, ya ha acordado un protocolo que ambas partes utilizarán para comunicarse entre sí. El protocolo es el formato de archivo. – Reginaldo

0

En C++, debe tener mucho cuidado si desea escribir código que funcione indiferentemente en 32 o 64 bits. Muchas personas asumen erróneamente que int puede almacenar un puntero, por ejemplo.

+0

Nunca he tenido problemas con eso. He tenido problemas a lo largo de los años con personas que pensaban que int era lo mismo que size_t. –

+1

No se presupone el ancho de un tipo (cuando no coincide así) simplemente mala práctica de programación? : P –

+1

Oh, sí, lo es. Sin embargo, es una práctica de programación común. Lo noté por primera vez cuando enseñaba en un libro de texto que sugería probar "printf (" Tamaño de int es% d \ n ", sizeof (int));" y un estudiante obtuvo cero impreso - en un sistema big-endian donde int era de 16 bits y size_t 32. –

15

Saber cómo funcionan las cosas, ya sea cómo funciona la máquina virtual y cómo funciona en su plataforma, o cómo ciertas construcciones de C++ se transforman en ensamblaje siempre lo hará un mejor programador, porque comprenderá por qué deberían ser las cosas hecho como son.

Necesita comprender cosas como la memoria para saber qué cache-falla y por qué podrían afectar su programa. Debes saber cómo se implementan ciertas cosas, aunque solo uses una interfaz o una forma de alto nivel para llegar a ella, saber cómo funciona te asegurará que lo estás haciendo de la mejor manera.

Para el trabajo por paquetes, necesita comprender cómo se almacenan los datos en las plataformas y cómo el envío a través de la red a una plataforma diferente puede cambiar la forma en que se leen los datos (endian-ness).

Su compilador hará el mejor uso de la plataforma en la que está compilando, por lo tanto, si se apega a los estándares y códigos bien, puede ignorar la mayoría y asumir que el compilador sacará lo mejor.

Así que, en resumen, no. No necesita saber las cosas de bajo nivel, pero nunca está de más saber.

+0

Estoy totalmente de acuerdo contigo – g06lin

+1

El último bit está muy bien puesto: "nunca está de más saberlo" – BCS

1

Si está programando en Python o en Java, el intérprete y la máquina virtual, respectivamente, el extracto esta capa de la arquitectura. Entonces no necesita preocuparse si se está ejecutando en una arquitectura de 32 o 64 bits.

Lo mismo no puede decirse de C++, en la que se le tiene que preguntarse a veces si se está ejecutando en una máquina de 32 o 64 bits

3

En Java y Python, detalles de la arquitectura se abstraen de distancia para que se de hecho es más o menos imposible escribir código dependiente de la arquitectura.

Con C++, esta es una cuestión completamente diferente: puede escribir código que no dependa de los detalles de la arquitectura, pero debe evitar las trampas, específicamente con respecto a los tipos de datos básicos dependientes de la arquitectura, como int.

6

A veces tiene que molestarse.

Puede que se sorprenda cuando estos detalles de bajo nivel de repente saltan y te muerden. Por ejemplo, Java estandarizó double para ser de 64 bits. Sin embargo, Linux JVM utiliza el modo de "precisión extendida", cuando el doble tiene 80 bits mientras está en el registro de la CPU. Esto significa que el siguiente código puede fallar:

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

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

assert(y == x); 

Simplemente porque y es forzado a salir del registro en la memoria y truncada de 80 a 64 bits.

+1

¿No significa esto que la JVM de Linux no es estándar? IIRC, Java define operaciones en coma flotante con gran detalle. –

+1

Ese ejemplo demuestra algo más: el implementador del tiempo de ejecución del lenguaje necesita comprender la definición del lenguaje correctamente. Eso simplemente se rompe. Ningún programador de Java debería tener que aguantar eso. –

+2

Sí, esto es un error Esto fue reportado como un error en GNU Java, pero fue ignorado: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16122 –

2

Siempre que haga las cosas correctamente, casi nunca necesitará saber para la mayoría de los idiomas. En muchos casos, nunca necesita saber, ya que el comportamiento del lenguaje no varía (Java, por ejemplo, especifica el comportamiento del tiempo de ejecución de forma precisa).

En C++ y C, hacer las cosas correctamente incluye no hacer suposiciones sobre int. No coloque punteros en int, y cuando esté haciendo algo con tamaños de memoria o direcciones use size_t y ptrdiff_t. No cuente con el tamaño de los tipos de datos: int debe tener al menos 16 bits, casi siempre es 32 y puede ser 64 en algunas arquitecturas. No suponga que la aritmética de coma flotante se realizará exactamente de la misma manera en máquinas diferentes (los estándares IEEE tienen un margen de maniobra).

Casi todos los sistemas operativos que soportan las redes le dará una cierta manera de hacer frente a posibles problemas endianness. Usalos, usalos a ellos. Utilice las funciones de idioma como isalpha() para clasificar los caracteres, en lugar de operaciones aritméticas en los caracteres (lo que podría ser algo extraño como EBCDIC). (Por supuesto, ahora es más habitual usar wchar_t como tipo de carácter, y usar Unicode internamente.)

6

La última vez que miré la especificación de lenguaje Java, contenía un ridículo getcha en la sección sobre el boxeo de enteros.

Integer a = 100; 
Integer b = 100; 

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

Que se garantiza que imprima true.

Integer a = 300; 
Integer b = 300; 

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

No se garantiza que imprima true. Depende del tiempo de ejecución. La especificación lo dejó completamente abierto. Es porque boxear un int entre -128 y 127 devuelve objetos "internados" (análogos a la forma en que se internan los literales de cadena), pero se recomienda que el implementador del tiempo de ejecución del lenguaje eleve ese límite si lo desea.

personalmente considerar que como una decisión loca, y espero que he arreglado ya que (escribir una vez, ejecutar en cualquier lugar?)

+0

usted encontró más una decisión de diseño estúpida de Java – GogaRieger

+0

interesante ... ¡Mirar en los detalles de los objetos "internados"! En una JVM 1.6.0_14 en un sistema Linux x86 de 32 bits, me da verdadero siempre que a & b sea <128. – g06lin

+0

Tengo el tamaño correcto, pero está firmado (-128 a 127) - ver http: //java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7 –

0

con Java y .NET que realmente no tiene que molestarse con él a menos estás haciendo cosas de muy bajo nivel, como trozos de juguete. Si está usando c, C++, fortran, podría pasar, pero en realidad recomendaría usar cosas como "stdint.h", donde usa declaraciones definitivas, como uint64_t y uint32_t, para que sean explícitas. Además, deberá compilar con bibliotecas en particular, según cómo se vincule, por ejemplo, un sistema de 64 bits podría usar gcc en un modo de compilación predeterminado de 64 bits.

0

Una máquina de 32 bits le permitirá tener un máximo de 4 GB de memoria virtual direccionable. (En la práctica, es incluso menor que eso, generalmente 2 GB o 3 GB dependiendo del sistema operativo y varias opciones del enlazador). En una máquina de 64 bits, puede tener un enorme espacio de direcciones virtuales (en cualquier sentido práctico, limitado solo por disco)) y una RAM bastante grande.

Así que si espera conjuntos de datos de 6GB para algunos cálculos (digamos algo que necesita acceso incoherente y no puede ser transmitido un poco a la vez), en una arquitectura de 64 bits podría leerlo en RAM y haga sus cosas, mientras que en una arquitectura de 32 bits necesita una forma fundamentalmente diferente de abordarlo, ya que simplemente no tiene la opción de mantener el conjunto de datos completo como residente.

Cuestiones relacionadas