c++ - Arquitecturas exóticas de las que se preocupan los comités de estándares
architecture (7)
Sé que los estándares C y C ++ dejan muchos aspectos de la implementación del lenguaje, definidos simplemente porque si hay una arquitectura con otras características, sería muy difícil o imposible escribir un compilador estándar conforme.
Sé que hace 40 años cualquier computadora tenía su propia especificación única. Sin embargo, no conozco ninguna arquitectura utilizada hoy en día donde:
CHAR_BIT != 8
-
signed
no es complemento de dos (escuché que Java tenía problemas con este). - El punto flotante no cumple con IEEE 754 (Editar: quise decir "no en codificación binaria IEEE 754").
La razón por la que estoy preguntando es que a menudo le explico a la gente que es bueno que C ++ no exija ningún otro aspecto de bajo nivel como los tipos de tamaño fijo † . Es bueno porque a diferencia de "otros idiomas" hace que su código sea portátil cuando se usa correctamente (Editar: porque puede trasladarse a más arquitecturas sin requerir emulación de aspectos de bajo nivel de la máquina, como por ejemplo aritmética de complemento de dos en arquitectura de signo + magnitud) . Pero me siento mal por no poder señalar ninguna arquitectura específica yo mismo.
Entonces la pregunta es: ¿qué arquitecturas exhiben las propiedades anteriores?
† uint*_t
s son opcionales.
CHAR_BITS
De acuerdo con el código fuente de gcc :
CHAR_BIT
es de 16
bits para las arquitecturas 1750a , dsp16xx .
CHAR_BIT
es de 24
bits para la arquitectura dsp56k .
CHAR_BIT
es de 32
bits para la arquitectura c4x .
Puedes encontrar más fácilmente haciendo lo siguiente:
find $GCC_SOURCE_TREE -type f | xargs grep "#define CHAR_TYPE_SIZE"
o
find $GCC_SOURCE_TREE -type f | xargs grep "#define BITS_PER_UNIT"
si CHAR_TYPE_SIZE
está apropiadamente definido.
Cumplimiento con IEEE 754
Si la arquitectura de destino no es compatible con las instrucciones de coma flotante, gcc puede generar la caída de software que no es el estándar compatible por defecto. Además, se pueden usar opciones especiales (como -funsafe-math-optimizations
que también desactivan la preservación de signos para ceros).
Eche un vistazo a este
Unisys ClearPath Dorado Servers
ofreciendo compatibilidad con versiones anteriores para personas que aún no han migrado todo su software Univac.
Puntos clave:
- Palabras de 36 bits
-
CHAR_BIT == 9
- el complemento de uno
- Punto flotante no IEEE de 72 bits
- espacio de direcciones separado para código y datos
- palabra dirigida
- sin puntero de pila dedicado
No sé si ofrecen un compilador de C ++, pero podrían hacerlo.
Y ahora ha aparecido un enlace a una edición reciente de su manual C:
Manual de referencia de programación del compilador Unisys C
La Sección 4.5 tiene una tabla de tipos de datos con 9, 18, 36 y 72 bits.
El cumplimiento completo de IEEE 754 es raro en implementaciones de coma flotante. Y debilitar la especificación en ese sentido permite muchas optimizaciones.
Por ejemplo, la subnorm admite diferencias entre x87 y SSE.
Las optimizaciones como fusionar una multiplicación y una suma que estaban separadas en el código fuente también cambian ligeramente los resultados, pero es una buena optimización en algunas arquitecturas.
O bien, en x86, el estricto cumplimiento de IEEE podría requerir el establecimiento de determinados indicadores o transferencias adicionales entre los registros de punto flotante y la memoria normal para obligarlo a usar el tipo de punto flotante especificado en lugar de sus flotantes de 80 bits internos.
Y algunas plataformas no tienen flotadores de hardware y, por lo tanto, necesitan emularlas en el software. Y algunos de los requisitos de IEEE 754 pueden ser costosos de implementar en el software. En particular, las reglas de redondeo pueden ser un problema.
Mi conclusión es que no necesita arquitecturas exóticas para entrar en situaciones en las que no siempre quiere garantizar el cumplimiento estricto de IEEE. Por este motivo, pocos lenguajes de programación garantizan el estricto cumplimiento de IEEE.
Encontré este enlace que enumera algunos sistemas donde CHAR_BIT != 8
. Incluyen
algunos DSP de TI tienen
CHAR_BIT == 16
Chip BlueCore-5 (un chip Bluetooth de Cambridge Silicon Radio) que tiene
CHAR_BIT == 16
.
Y, por supuesto, hay una pregunta sobre : qué plataformas tienen algo más que char de 8 bits
En cuanto a los sistemas que no son complementos de dos, hay una lectura interesante en comp.lang.c ++ moderada . Resumido: hay plataformas que tienen el complemento de uno o la representación de signo y magnitud.
Estoy bastante seguro de que los sistemas VAX todavía están en uso. No son compatibles con el punto flotante IEEE; usan sus propios formatos. Alpha admite formatos de punto flotante VAX e IEEE.
Las máquinas vectoriales Cray, como la T90, también tienen su propio formato de coma flotante, aunque los sistemas Cray más nuevos usan IEEE. (El T90 que utilicé fue retirado del servicio hace algunos años; no sé si alguno todavía está en uso activo).
El T90 también tenía / tiene algunas representaciones interesantes para punteros y números enteros. Una dirección nativa solo puede apuntar a una palabra de 64 bits. Los compiladores C y C ++ tenían CHAR_BIT == 8 (necesario porque ejecutaba Unicos, un sabor de Unix, y tenía que interoperar con otros sistemas), pero una dirección nativa solo podía apuntar a una palabra de 64 bits. Todas las operaciones de nivel de byte fueron sintetizadas por el compilador, y un void*
o char*
almacenó un desplazamiento de bytes en los 3 bits de orden superior de la palabra. Y creo que algunos tipos enteros tenían bits de relleno.
Los mainframes de IBM son otro ejemplo.
Por otro lado, estos sistemas particulares no necesariamente excluyen los cambios en el estándar de idioma. Cray no mostró ningún interés particular en actualizar su compilador de C a C99; presumiblemente lo mismo se aplica al compilador de C ++. Puede ser razonable ajustar los requisitos para implementaciones alojadas, como CHAR_BIT == 8, formato flotante IEEE si no es la semántica completa, y complemento de 2 sin bits de relleno para enteros con signo. Los sistemas antiguos podrían seguir siendo compatibles con los estándares de idiomas anteriores (C90 no murió cuando salió C99), y los requisitos podrían ser más flexibles para las implementaciones independientes (sistemas integrados) como los DSP.
Por otro lado, podría haber buenas razones para que los sistemas futuros hagan cosas que hoy se considerarían exóticas.
La representación binaria de IEEE 754 no era común en las GPU hasta hace poco, consulte GPU Paranoia de coma flotante .
EDITAR: se ha planteado una pregunta en los comentarios sobre si el punto flotante de la GPU es relevante para la programación habitual de la computadora, sin relación con los gráficos. ¡Oh sí! La mayoría de las cosas de alto rendimiento calculadas industrialmente hoy en día se hace en GPU; la lista incluye AI, minería de datos, redes neuronales, simulaciones físicas, pronóstico del tiempo y mucho más. Uno de los enlaces en los comentarios muestra por qué: una ventaja de punto flotante de orden de magnitud de las GPU.
Otra cosa que me gustaría añadir, que es más relevante para la pregunta de OP: ¿qué hizo la gente hace 10-15 años cuando el punto flotante de GPU no era IEEE y cuando no había API como OpenCL o CUDA de hoy para programar GPU? Lo creas o no, los primeros pioneros en computación de la GPU lograron programar GPU sin una API para hacer eso . Conocí a uno de ellos en mi compañía. Esto es lo que hizo: codificó los datos que necesitaba para calcular como una imagen con píxeles que representaban los valores en los que estaba trabajando y luego utilizó OpenGL para realizar las operaciones que necesitaba (como "desenfoque gaussiano" para representar una convolución con una distribución normal , etc.) y decodificó la imagen resultante en una matriz de resultados. ¡Y esto todavía era más rápido que usar la CPU!
Este tipo de cosas es lo que llevó a NVidia a finalmente hacer que sus datos internos binarios sean compatibles con IEEE e introducir una API orientada a la computación en lugar de a la manipulación de imágenes.
Ninguna de sus suposiciones es válida para mainframes. Para empezar, no conozco un mainframe que use IEEE 754: IBM usa base 16 coma flotante, y los dos mainframes de Unisys usan base 8. Las máquinas Unisys son un poco especiales en muchos otros aspectos: Bo mencionó el 2200 arquitectura, pero la arquitectura MPS es aún más extraña: palabras etiquetadas de 48 bits. (Si la palabra es un puntero o no, depende de un bit en la palabra.) Y las representaciones numéricas están diseñadas para que no haya una distinción real entre el punto flotante y la aritmética integral: el punto flotante es la base 8; no requiere normalización, y a diferencia de todos los demás puntos flotantes que he visto, pone el decimal a la derecha de la mantisa, en lugar de la izquierda, y utiliza la magnitud con signo para el exponente (además de la mantisa). Con los resultados, un valor de coma flotante integral tiene (o puede tener) exactamente la misma representación de bit que un entero de magnitud con signo. Y no hay instrucciones aritméticas de coma flotante: si los exponentes de los dos valores son ambos 0, la instrucción realiza aritmética integral, de lo contrario, realiza aritmética de coma flotante. (Una continuación de la filosofía de etiquetado en la arquitectura.) Lo que significa que mientras int
puede ocupar 48 bits, 8 de ellos deben ser 0, o el valor no se tratará como un número entero.