Pregunta

I hizo una spinlock muy simple de utilizar las funciones entrelazadas en Windows y probado en una CPU de doble núcleo (dos hilos que se incrementan una variable);

El programa parece funcionar bien (se da el mismo resultado cada vez, lo cual no es el caso cuando no se utiliza la sincronización), pero Intel Parallel Inspector dice que existe una condición de carrera en < em> valor + = j (véase el código de abajo). La advertencia desaparece cuando se utiliza secciones críticas en lugar de mi SpinLock.

Es mi implementación de SpinLock correcta o no? Es realmente extraño, porque todas las operaciones utilizadas son atómica y tienen las barreras de memoria adecuados y no debe dar lugar a condiciones de carrera.

class SpinLock
{
   int *lockValue;
   SpinLock(int *value) : lockValue(value) { }

   void Lock() {
      while(InterlockedCompareExchange((volatile LONG*)lockValue, 1, 0) != 0) {
          WaitABit();
      }
   }

   void Unlock() { InterlockedExchange((volatile LONG*)lockValue, 0); }
};

El programa de pruebas:

static const int THREADS = 2;
HANDLE completedEvents[THREADS];
int value = 0;
int lock = 0; // Global.

DWORD WINAPI TestThread(void *param) {
    HANDLE completed = (HANDLE)param;
    SpinLock testLock(&lock);

    for(int i = 0;i < 1000*20; i++) {
        for(int j = 0;j < 10*10; j++) {
            // Add something to the variable.
            testLock.Lock();
            value += j;
            testLock.Unlock();
        }
    }
    SetEvent(completed);
}

int main() {
   for(int i = 0; i < THREADS; i++) {
        completedEvents[i] = CreateEvent(NULL, true, false, NULL);
   }
   for(int i = 0; i < THREADS; i++) {
        DWORD id;
        CreateThread(NULL, 0, TestThread, completedEvents[i], 0, &id);
   }

   WaitForMultipleObjects(THREADS, completedEvents, true, INFINITE);
   cout<<value;
}
¿Fue útil?

Solución

documentación del Inspector paralelo para carrera de datos sugiere el uso de una sección crítica o un mutex para fijar carreras en Windows. No hay nada en ella que sugiere que el inspector paralelo sabe reconocer cualquier otro mecanismo de bloqueo es posible que inventar.

Herramientas para el análisis de nuevos mecanismos de cierre tienden a ser herramientas estáticas que se ven en cada camino posible a través del código, la documentación del Inspector paralelo implica que se ejecuta el código una vez.

Si usted quiere experimentar con nuevos mecanismos de bloqueo, la herramienta más común que he visto en la literatura académica es la vuelta comprobador de modelos . También hay ESP , lo que podría reducir el espacio de estados, pero no lo hago saber si se ha aplicado a los problemas concurrentes, y también el banco de trabajo de la movilidad cual daría un análisis si se puede sofá de su problema en el pi-cálculo. Inspector paralelo Intel no parece nada por el estilo tan complicado como estas herramientas, sino más bien diseñado para comprobar si hay problemas que ocurren comúnmente utilizando la heurística.

Otros consejos

Para otras personas pobres en una situación similar a mí: Intel proporciona un conjunto de bibliotecas incluye y para hacer exactamente este tipo de cosas. Compruebe en el directorio de instalación Inspector (verá \ incluir, \ lib32 y \ lib64 en el directorio de instalación) para esos materiales. Documentación sobre la forma de utilizarlos (a junio de 2018, aunque Intel no le importa nada acerca de mantener vínculos coherentes):

https: // software .intel.com / es-eS / inspector-user-guía-windows-API-para-aduana-sincronización

Hay 3 funciones:

void __itt_sync_acquired(void *addr)
void __itt_sync_releasing(void *addr)
void __itt_sync_destroy(void *addr)

Estoy bastante seguro de que debe ser implementado de la siguiente manera:

class SpinLock
{
   long lockValue;
   SpinLock(long value) : lockValue(value) { }

   void Lock() {
      while(InterlockedCompareExchange(&lockValue, 1, 0) != 0) {
          WaitABit();
      }
   }

   void Unlock() { InterlockedExchange(&lockValue, 0); }
};
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top