Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

200
Visualizações
¿Se permite que un compilador de C fusione asignaciones secuenciales a variables volátiles?

Tengo un problema de hardware teórico (no determinista, difícil de probar, nunca sucedió en la práctica) informado por el proveedor de hardware donde la escritura de dos palabras en ciertos rangos de memoria puede dañar cualquier transferencia de bus futura.

Si bien no tengo ninguna escritura de palabra doble explícitamente en el código C, me preocupa que el compilador pueda (en implementaciones actuales o futuras) unir varias asignaciones de palabras adyacentes en una sola asignación de palabra doble.

El compilador no puede reordenar asignaciones de volátiles, pero no está claro (para mí) si la fusión cuenta como reordenación. Mi instinto dice que lo es, ¡pero ya he sido corregido por abogados lingüísticos antes!

Ejemplo:

 typedef struct { volatile unsigned reg0; volatile unsigned reg1; } Module; volatile Module* module = (volatile Module*)0xFF000000u; // two word stores, or one double-word store? module->reg0 = 1; module->reg1 = 2;

(Le preguntaré a mi proveedor de compilador sobre esto por separado, pero tengo curiosidad por saber cuál es la interpretación canónica/comunitaria del estándar).

over 4 years ago · Santiago Trujillo
5 Respostas
Responde à pergunta

0

No, el compilador no puede optimizar esas dos escrituras en una sola escritura de doble palabra. Es un poco difícil citar el estándar ya que la parte relacionada con las optimizaciones y los efectos secundarios está escrita de manera muy confusa. Las partes relevantes se encuentran en C17 5.1.2.3:

Las descripciones semánticas de esta Norma Internacional describen el comportamiento de una máquina abstracta en la que las cuestiones de optimización son irrelevantes.

Acceder a un objeto volátil, modificar un objeto, modificar un archivo o llamar a una función que realiza cualquiera de esas operaciones son todos efectos secundarios, que son cambios en el estado del entorno de ejecución.

En la máquina abstracta, todas las expresiones se evalúan según lo especificado por la semántica. Una implementación real no necesita evaluar parte de una expresión si puede deducir que su valor no se usa y que no se producen efectos secundarios necesarios (incluidos los causados por llamar a una función o acceder a un objeto volátil).

Los accesos a objetos volátiles se evalúan estrictamente de acuerdo con las reglas de la máquina abstracta.

Cuando accede a parte de una estructura, eso en sí mismo es un efecto secundario, que puede tener consecuencias que el compilador no puede determinar. Supongamos, por ejemplo, que su estructura es un mapa de registro de hardware y esos registros deben escribirse en un orden determinado. Como, por ejemplo, alguna documentación del microcontrolador podría estar en la línea de: "reg0 habilita el periférico de hardware y debe escribirse antes de poder configurar los detalles en reg1".

Un compilador que combinaría las escrituras de objetos volatile en uno solo sería no conforme y simplemente estaría roto.

over 4 years ago · Santiago Trujillo Relatório

0

Cambiarlo cambiará el comportamiento observable del programa. Por lo tanto, el compilador no puede hacerlo.

over 4 years ago · Santiago Trujillo Relatório

0

El compilador no puede hacer dos asignaciones de este tipo en una sola escritura de memoria. Debe haber dos escrituras independientes desde el núcleo. La respuesta de @Lundin brinda referencias relevantes al estándar C.

Sin embargo, tenga en cuenta que un caché, si está presente, puede engañarlo. La palabra clave volatile no implica memoria "no almacenada en caché". Entonces, además de usar volatile , también debe asegurarse de que la dirección 0xFF000000 esté asignada como no almacenada en caché. Si la dirección se asigna como almacenada en caché, el HW de caché puede convertir las dos asignaciones en una sola escritura de memoria. En otras palabras, para la memoria caché, las operaciones de escritura de memoria de dos núcleos pueden terminar como una sola operación de escritura en la interfaz de memoria del sistema.

over 4 years ago · Santiago Trujillo Relatório

0

El estándar C es independiente de cualquier relación entre operaciones en objetos volátiles y operaciones en la máquina real. Si bien la mayoría de las implementaciones especificarían que una construcción como *(char volatile*)0x1234 = 0x56; generaría un almacén de bytes con el valor 0x56 a la dirección de hardware 0x1234, una implementación podría, en su tiempo libre, asignar espacio para, por ejemplo, una matriz de 8192 bytes y especificar que *(char volatile*)0x1234 = 0x56; almacenaría inmediatamente 0x56 en el elemento 0x1234 de esa matriz, sin hacer nada con la dirección de hardware 0x1234. Alternativamente, una implementación puede incluir algún proceso que almacene periódicamente lo que sea que esté en 0x1234 de esa matriz en la dirección de hardware 0x56.

Todo lo que se requiere para la conformidad es que todas las operaciones en objetos volátiles dentro de un solo hilo, desde el punto de vista de la máquina abstracta , se consideren absolutamente secuenciadas. Desde el punto de vista del Estándar, las implementaciones pueden convertir dichos accesos en operaciones de máquinas reales de la forma que consideren adecuada.

over 4 years ago · Santiago Trujillo Relatório

0

El comportamiento de volatile parece depender de la implementación, en parte debido a una oración curiosa que dice: "Lo que constituye un acceso a un objeto que tiene un tipo calificado como volátil está definido por la implementación".

En ISO C 99, sección 5.1.2.3, también hay:

3 En la máquina abstracta, todas las expresiones se evalúan según lo especificado por la semántica. Una implementación real no necesita evaluar parte de una expresión si puede deducir que su valor no se usa y que no se producen efectos secundarios necesarios (incluidos los causados por llamar a una función o acceder a un objeto volátil ).

Entonces, aunque se dan requisitos de que un objeto volatile debe tratarse de acuerdo con la semántica abstracta (es decir, no optimizado), curiosamente, la semántica abstracta en sí misma permite la eliminación de código muerto y flujos de datos, ¡que son ejemplos de optimizaciones!

Me temo que para saber qué hará y qué no hará volatile , debe consultar la documentación de su compilador.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda