_ReadWriteBarrier

Específicos de Microsoft

Fuerza lee y escribe en memoria para completar actualmente la llamada.

Nota de precauciónPrecaución

_ReadBarrier, _WriteBarrier, Y los intrínsecos del compilador de _ReadWriteBarrier evitan sólo reordenar del compilador.Para evitar que la CPU reordenar operaciones de lectura y escritura, utilice la macro de MemoryBarrier .

void _ReadWriteBarrier(void);

Requisitos

Intrínseco

Arquitectura

_ReadWriteBarrier

x86, IPF, x64

Archivo de encabezado <intrin.h>

Comentarios

_ReadBarrier, _WriteBarrier, y la ayuda de las funciones de _ReadWriteBarrier aseguran la operación correcta de los programas multiproceso que están optimizados por el compilador de Visual C++ .Un programa correctamente optimizado produce el mismo resultado cuando se ejecuta en varios subprocesos como cuando se ejecuta en un subproceso único.

El punto en una aplicación donde _ReadBarrier, _WriteBarrier, o la función de _ReadWriteBarrier se ejecuta se denomina una barrera de memoria.Una barrera de memoria puede estar para las lecturas, escribe, o ambas.

Una instrucción que tiene acceso una variable en memoria se pueden eliminar o mover a través de una barrera de memoria como parte de una optimización.Por consiguiente, un subproceso puede leer un valor anterior de una variable global antes de que otro subproceso finalice la escritura de un nuevo valor a la variable, o escriba un nuevo valor antes de que otro subproceso finalice leer un valor anterior de la variable.

Para asegurarse de que el programa optimizado funciona correctamente, la función de _ReadWriteBarrier fuerza lee y escribe en memoria para completar actualmente la llamada.Después de la llamada, otros subprocesos pueden tener acceso a la memoria sin miedo que el subproceso que realice la llamada podría tener una lectura pendiente o escribir en la memoria.Una barrera de memoria evita que el compilador optimiza accesos de memoria mediante la barrera, pero los permisos el compilador aún para optimizar instrucciones entre las barreras.

Memoria de marca con una barrera de memoria es similar a marcar la memoria con la palabra clave de volatile (C++) .Sin embargo, una barrera de memoria es más eficaz porque lee y escribe se convierten para completar en puntos concretos del programa en lugar de global.Optimizaciones que pueden producirse si se utiliza una barrera de memoria no pueden aparecer si la variable se declara volatile.

[!NOTA]

En las últimas versiones del compilador de Visual C++ , _ReadWriteBarrier y las funciones de _WriteBarrier se aplicaran solo localmente y no afectaron a funciones en todo el árbol de llamadas.Estas funciones se aplican hasta el final sobre el árbol de llamadas.

Memoria afectada

Las variables globales se ven afectadas por las barreras de memoria, pero las variables locales no se normalmente.La mayoría de las variables locales no son accesibles a otros subprocesos y por consiguiente no necesitan la protección.Una variable se ve afectada por una barrera de memoria si cumple una de las condiciones siguientes:

  • La variable es una variable global.

  • La variable es una variable local utilizada en __try, __except, o __finally bloquea si se utiliza el control de excepciones estructurado, o captura bloquea si se utiliza el control de excepciones de C++.Para obtener más información, vea la opción del compilador /EHa .

  • La variable es una variable local que se declara volatile.

  • La variable es una variable local cuya dirección con la función actual de alguna manera.Por ejemplo, la variable se pasa por referencia a otra función o asignan su dirección a una variable global.

  • La variable se obtiene acceso indirectamente a través de un puntero y el puntero desreferenciado cumple una de las condiciones anteriores.El caso más habitual es *p donde es una variable global o un parámetro p .

Ejemplo

// intrinsics_readwritebarrier.c
// compile with: /O2 -DNO_BARRIER
// This code contains an error--dereferencing a null pointer--
// which will be optimized away as a useless assignment.
// Omit the NO_BARRIER command line to activate the Write Barrier.
// With the barrier activated, the assignment is not optimized away
// and causes an access violation.

#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
#include <stdio.h>
#include <intrin.h>

#pragma intrinsic(_ReadWriteBarrier)

int x = 0;

__declspec(noinline) int f(int* p)
{
    x = *p;
#ifndef NO_BARRIER
    _ReadWriteBarrier();
#endif
    x = 7;
    return x;
}


// If code is EXCEPTION_ACCESS_VIOLATION it means an
// attempt to read from the NULL pointer we passed in, so
// we handle the exception.
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
    if (code == EXCEPTION_ACCESS_VIOLATION)
    {
        printf_s("AV\n");
        return EXCEPTION_EXECUTE_HANDLER;
    }

    // If not what we were looking for, we don't want to handle it.
    return EXCEPTION_CONTINUE_SEARCH;
}

int main()
{
    int nRet = 0;

    __try
    {
        // Should return only if the first assignment is
        // optimized away.
        nRet = f(NULL);
        printf_s("Assignment was optimized away!\n");
    }
    __except(filter(GetExceptionCode(), GetExceptionInformation()))
    {
        // We get here if an Access violation occurred.
        printf_s("Access Violation: assignment was not optimized away.\n");
    }
}
  

Vea también

Referencia

_ReadBarrier

_WriteBarrier

Función intrínseca del compilador

Palabras clave de C++