Arquitecturas exóticas de las que se preocupan los comités de estándares

Sé que los estándares C y C ++ dejan muchos aspectos de la implementación del lenguaje, definidos simplemente porque si hay una architecture con otras características, sería muy difícil o imposible escribir un comstackdor estándar conforme.

Sé que hace 40 años cualquier computadora tenía su propia especificación única. Sin embargo, no conozco ninguna architecture 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 encoding 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 architectures sin requerir emulación de aspectos de bajo nivel de la máquina, como por ejemplo aritmética de complemento de dos en architecture de signo + magnitud) . Pero me siento mal por no poder señalar ninguna architecture específica yo mismo.

Entonces la pregunta es: ¿qué architectures exhiben las propiedades anteriores?

uint*_t s son opcionales.

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 stack dedicado

No sé si ofrecen un comstackdor 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 progtwigción del comstackdor Unisys C

La Sección 4.5 tiene una tabla de tipos de datos con 9, 18, 36 y 72 bits.

tamaño y rango de tipos de datos en el compilador C de USC

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 architecture, pero la architecture 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 architecture.) 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.

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 sum que estaban separadas en el código fuente también cambian ligeramente los resultados, pero es una buena optimización en algunas architectures.

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 architectures exóticas para entrar en situaciones en las que no siempre quiere garantizar el cumplimiento estricto de IEEE. Por este motivo, pocos lenguajes de progtwigció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 Stack Overflow: 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 comstackdores 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 comstackdor, 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 comstackdor de C a C99; presumiblemente lo mismo se aplica al comstackdor 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.

CHAR_BITS

De acuerdo con el código fuente de gcc :

CHAR_BIT es de 16 bits para las architectures 1750a , dsp16xx .
CHAR_BIT es de 24 bits para la architecture dsp56k .
CHAR_BIT es de 32 bits para la architecture 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 architecture 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).

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 progtwigció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 progtwigr GPU? Lo creas o no, los primeros pioneros en computación de la GPU lograron progtwigr 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.