Me encontré con la función InterlockedExchange y me preguntaba cuándo debería usar esta función. En mi opinión, establecer un valor de 32 Bit en un procesador x86 siempre debe ser atómico.
En el caso en que deseo usar la función, el nuevo valor no depende del valor anterior (no es una operación de incremento). Podría dar un ejemplo en este método es obligatorio (no estoy en busca de InterlockedCompareExchange)¿Cuándo debería utilizarse la función Winlock InterlockedExchange?
Respuesta
En una máquina multiprocesador o multinúcleo, cada núcleo tiene su propio caché, por lo que cada núcleo tiene cada una de ellas una "vista" potencialmente diferente de lo que es el contenido de la memoria del sistema.
mecanismos de sincronización de rosca se encargan de la sincronización entre los núcleos, para más información ver http://blogs.msdn.com/oldnewthing/archive/2008/10/03/8969397.aspx o Google para adquirir y liberar la semántica
InterlockedExchange
es tanto una escritura y una lectura - devuelve el valor anterior.
Esto es necesario para garantizar que otro subproceso no escriba un valor diferente justo después de que lo hizo. Por ejemplo, supongamos que estás tratando de incrementar una variable. Puede leer el valor, agregar 1, luego establecer el nuevo valor con InterlockedExchange
. El valor devuelto por InterlockedExchange
debe coincidir con el valor que leyó originalmente, de lo contrario, probablemente otro subproceso lo incremente al mismo tiempo, y deberá volver a intentarlo y volver a intentarlo.
En este caso, yo usaría InterlockedCompareExchange, porque el control de si el valor todavía era el original ya está hecho por el método. – EFrank
O simplemente InterlockedIncrement –
Además de escribir el nuevo valor, InterlockedExchange
también lee y devuelve el valor anterior; toda esta operación es atómica. Esto es útil para lock-free algorithms.
(Por cierto, las escrituras de 32 bits son no garantiza que sea atómica. Consideremos el caso en que la escritura es no alineada y extiende a ambos lados de un límite de caché, por ejemplo.)
Sería atómico desde el punto de vista del software que se ejecuta en el procesador, pero no desde el punto de vista del hardware que se encuentra en el bus. –
¿Sería atómico desde el punto de vista del software que se ejecuta en otro núcleo? ¿Qué pasa con una escritura que se extiende a lo largo de un límite de página y desencadena una falla? Han pasado años desde que hice alguna codificación x86 de bajo nivel, supongo que puedo estar mintiendo:/ – moonshadow
establecer un valor de 32 bits es atómico, pero solo si estás estableciendo un literal.
b = a es de 2 operaciones:
mov eax,dword ptr [a]
mov dword ptr [b],eax
Teóricamente podría haber algunos interrupción entre la primera y segunda operación.
Y si hubiera alguna interrupción, ¿qué? Tomará un poco más de tiempo, pero el valor en eax no cambiará. El verdadero objetivo de InterlockedExchange es que es de lectura y escritura atómica. – Suma
¿Entonces qué? Infierno. La interrupción puede causar una llamada al sistema, el sistema llama a un interruptor de contexto y luego otro hilo cambia el valor. Entonces EAX se restaura y el valor se cambia de nuevo. Las condiciones de carrera son especialmente fatales cuando se cuentan las referencias. Algunos subprocesos pueden incrementar el valor mientras que otro subproceso disminuye el valor, o dos subprocesos pueden incrementarlo al mismo tiempo. Que EAX se restaure no es la solución, es el problema. –
Y empeora cuando hay más de una CPU/núcleo. – SamB
Escribir un valor nunca es atómica por defecto. Cuando escribe un valor en una variable, se generan varias instrucciones de la máquina. Con sistemas operativos modernos y preventivos, el sistema operativo podría cambiar a otro hilo entre las operaciones individuales de la escritura.
Esto es incluso más un problema en las máquinas multiprocesador, donde varios subprocesos podrían estar ejecutándose al mismo tiempo, y tratando de escribir en una sola ubicación de memoria simultáneamente.
Las operaciones de enclavamiento evitan esto mediante el uso de instrucciones especializadas para realizar la escritura (x86 tiene instrucciones específicas para este tipo de situaciones), que hacen la lectura-modificación-escritura en una instrucción. Estas instrucciones también bloquean el bus de memoria de todos los procesadores, para garantizar que ningún otro hilo de ejecución pueda escribir en el valor al mismo tiempo.
-1, las escrituras alineadas incorrectas son atómicas en x86. – Johan
InterlockedExchange se asegura de que el cambio de una variable y el retorno de su valor original no sean interrumpidos por otros hilos.
lo tanto, si 'i' es un int, estas llamadas (tomados individualmente) no necesitan InterlockedExchange torno a 'i':
a = i;
i = 9;
i = a;
i = a + 9;
a = i + 9;
if(0 == i)
Ninguna de estas declaraciones invocar a la vez los valores inicial y final del ' yo'. Pero estas llamadas siguientes sí es necesario InterlockedExchange torno a 'i':
a = i++; //a = InterlockedExchange(&i, i + 1);
Sin ella, dos subprocesos que se ejecutan a través de este mismo código podría obtener el mismo valor de 'i' asignado a 'a' o 'a' puede saltar inesperadamente dos o más números
if(0 == i++) //if(0 == InterlockedExchange(&i, i + 1))
Dos subprocesos pueden ejecutar el código que solo se supone que debe ocurrir una vez.
etc.
Ejemplo incorrecto 'a = InterlockedExchange (& i, i + 1);'.Su 'i' podría ser cambiado por la otra CPU entre' i + 1' y 'InterlockedExchange'. – Fr0sT
guau, muchas respuestas contradictorias. Es difícil discernir quién tiene la razón, quién está equivocado y qué información es engañosa.
estoy seguro de la respuesta también, dadas las anteriores respuestas a medias, pero creo que funciona de esta manera, puedo estar equivocado, y será interesante averiguar si soy:
- lectura de 32 bits & escribe ARE atomic, pero dependiendo de su código, eso puede no significar mucho.
- no se preocupe por lecturas/escrituras no alineadas. TODAS las escrituras de 32 bits en una variable de 32 bits tienen que estar alineadas o las fallas de página de la máquina.
- no se preocupe por un ajuste de escritura al final de una página en caché, eso no puede suceder.
- Si necesita escribir y leer en un hilo y está escribiendo en otro hilo, entonces necesita usar InterlockedExchange. Si simplemente lees el valor en un hilo y lo escribes en otro, entonces no necesitas usarlo, pero esos valores pueden ser contundentes debido al multihilo.
-1 Los valores de 32 bits no necesitan alinearse en x86. Y las escrituras de 32 bits son atómicas en x86, pero no en muchas otras arquitecturas. – Johan
- 1. ¿Cuándo debería romper una función?
- 2. ¿Cuándo deberían utilizarse los sinónimos de la base de datos?
- 3. Alineación InterlockedExchange y memoria
- 4. ¿Cuándo debería usar return false en la función jquery?
- 5. ¿Cuándo debería usar call() frente a invocar la función directamente?
- 6. ¿Debería utilizarse Closeable como equivalente Java para IDisposable de .NET?
- 7. ¿Cuándo debería comenzar la automatización?
- 8. ¿Cómo funciona la serialización de Java y cuándo debería utilizarse en lugar de otra técnica de persistencia?
- 9. ¿Cuándo debería usar _aligned_malloc()?
- 10. ¿Cuándo debería usar std_logic_vector y cuándo debería usar otros tipos de datos?
- 11. ¿Cuándo debería implementar IDisposable?
- 12. Cuándo debería usar SynchronousQueue
- 13. ¿Cuándo debería usar semáforos?
- 14. ¿Cuándo debería almacenar una función en una variable?
- 15. Cuándo debería implementar __call__
- 16. ¿Cuándo debería iniciarse RVO?
- 17. ¿Cuándo debería usar CompiledQuery?
- 18. ¿Cuándo debería usar GC.SuppressFinalize()?
- 19. ¿Cuándo debería usar ConcurrentSkipListMap?
- 20. ¿Cuándo debería usar Silverlight y cuándo XNA?
- 21. ¿Cuándo debería usar TCP_NODELAY y cuándo TCP_CORK?
- 22. ¿Cuándo debería usar la palabra clave "self"?
- 23. ¿Cuándo debería usar la sintaxis "(function() {...})();"?
- 24. ¿Cuándo debería cerrar la conexión db?
- 25. ¿Cuándo debería usar html5 sessionStorage?
- 26. ¿Cuándo debería usar # en ColdFusion?
- 27. ¿Cuándo debería especificar explícitamente StructLayout?
- 28. ¿Cuándo debería usar un analizador?
- 29. ¿Cuándo debería usar marcos HTML?
- 30. ¿Cuándo debería escribir métodos estáticos?
Los cachés son secundarios aquí. Incluso si no hay cachés y las CPU hablaban con la memoria, la secuencia de lectura/escritura normal no es atómica. – Suma