En arquitectura de computadoras , la instrucción (o secuencia de instrucciones) de prueba y establecimiento de CPU está diseñada para implementar la exclusión mutua en entornos multiprocesador . Si bien se puede implementar un bloqueo correcto con la prueba y el establecimiento, la optimización de prueba y establecimiento reduce la contención de recursos causada por el bloqueo del bus, especialmente la sobrecarga del protocolo de coherencia de caché en bloqueos contenciosos.
Dado un bloqueo:
boolean locked := false // variable de bloqueo compartido
El protocolo de entrada es:
procedimiento EnterCritical() { hacer { mientras ( bloqueado == verdadero ) saltar // esperar usando instrucciones normales hasta que el bloqueo esté libre } mientras ( TestAndSet (bloqueado) == verdadero ) // intentar el bloqueo atómico real usando la instrucción de prueba y establecimiento }y el protocolo de salida es:
procedimiento ExitCritical() { bloqueado := falso }La diferencia con el protocolo simple de prueba y configuración radica en el bucle de espera adicional (la prueba en "prueba" y "prueba y configuración ") al inicio del protocolo de entrada, que utiliza instrucciones de carga ordinarias. La carga en este bucle se ejecuta con menor sobrecarga en comparación con una operación atómica (o una instrucción de carga exclusiva ). Por ejemplo, en un sistema que utiliza el protocolo de coherencia de caché MESI , la línea de caché que se está cargando pasa al estado Compartido, mientras que una instrucción de prueba y configuración o una instrucción de carga exclusiva la pasa al estado Exclusivo.
Esto resulta particularmente ventajoso si varios procesadores compiten por el mismo bloqueo: mientras que una instrucción atómica o una instrucción de carga exclusiva requiere una transacción de protocolo de coherencia para otorgar a ese procesador acceso exclusivo a la línea de caché (lo que provoca que esa línea opere de un lado a otro entre los procesadores involucrados), las cargas ordinarias en una línea en estado compartido no requieren ninguna transacción de protocolo: los procesadores que se ejecutan en el bucle interno operan de forma puramente local.
Las transacciones del protocolo de coherencia de caché se utilizan únicamente en el bucle externo, después de que la comprobación inicial haya determinado que tienen una probabilidad razonable de éxito.
Si el lenguaje de programación utilizado admite la evaluación en cortocircuito , el protocolo de entrada podría implementarse de la siguiente manera:
procedimiento EnterCritical() { mientras ( bloqueado == verdadero o TestAndSet(bloqueado) == verdadero ) saltar // esperar hasta que esté bloqueado }Advertencia
Si bien esta optimización es útil en la programación de sistemas , debe evitarse la técnica de prueba y configuración en la programación concurrente de alto nivel : el bloqueo en las aplicaciones impide que el planificador del sistema operativo sepa qué está bloqueando qué tarea. En consecuencia, el planificador tendrá que adivinar cómo asignar el tiempo de CPU entre los hilos, generalmente permitiendo que estos consuman su cuota de tiempo. Los hilos terminarán esperando improductivamente a que finalicen tareas que no están programadas.
Mediante el uso de objetos de bloqueo proporcionados por el sistema operativo, como los mutex, el sistema operativo puede programar con precisión los hilos que no están bloqueados.
Véase también
Referencias
- Gregory R. Andrews, Fundamentos de la programación multihilo, paralela y distribuida , págs. 100-101. Addison-Wesley, 2000. ISBN 0-201-35752-6.
- Control de concurrencia
- aritmética informática