Implemente un mutex de alto rendimiento similar al de Qt

Tengo una aplicación científica multihilo donde varios hilos informáticos (uno por núcleo) tienen que almacenar sus resultados en un búfer común. Esto requiere un mecanismo mutex.

Los subprocesos de trabajo dedican solo una pequeña fracción de su tiempo a escribir en el búfer, por lo que el mutex se desbloquea la mayor parte del tiempo y las cerraduras tienen una alta probabilidad de tener éxito inmediatamente sin esperar a que se desbloquee otro subproceso.

Actualmente, he usado QMutex de Qt para la tarea, y funciona bien: el mutex tiene una sobrecarga insignificante.

Sin embargo, tengo que portarlo solo a c ++ 11 / STL. Cuando se usa std :: mutex, el rendimiento disminuye en un 66% y los subprocesos pasan la mayor parte de su tiempo bloqueando el mutex.

Después de otra pregunta, pensé que Qt usa un mecanismo de bloqueo rápido basado en un indicador atómico simple, optimizado para casos en los que el mutex aún no está bloqueado. Y recurre a un mutex del sistema cuando se produce un bloqueo concurrente.

Me gustaría implementar esto en STL. ¿Hay una manera simple basada en std :: atomic y std :: mutex? He cavado en el código de Qt pero parece demasiado complicado para mi uso (no necesito bloqueos de tiempo de espera, pimpl, huella pequeña, etc.).

Editar: he intentado un spinlock, pero esto no funciona bien porque:

Periódicamente (cada pocos segundos), otro hilo bloquea los mutexes y vacía el búfer. Esto lleva algo de tiempo, por lo que todos los hilos de trabajo se bloquean en este momento. Los spinlocks hacen que la programación esté ocupada, lo que hace que el vaciado sea 10-100x más lento que con un mutex adecuado. Esto no es aceptable

Editar: he intentado esto, pero no funciona (bloquea todos los hilos)

class Mutex
{
public:
    Mutex() : lockCounter(0) { }

    void lock()
    {
        if(lockCounter.fetch_add(1, std::memory_order_acquire)>0)
        {
            std::unique_lock<std::mutex> lock(internalMutex);
            cv.wait(lock);
        }
    }

    void unlock();
    {
        if(lockCounter.fetch_sub(1, std::memory_order_release)>1)
        {
            cv.notify_one();
        }
    }


private:
    std::atomic<int> lockCounter;
    std::mutex internalMutex;
    std::condition_variable cv;
};

¡Gracias!

Editar: solución final

El mutex rápido de MikeMB funcionaba bastante bien.

Como solución final, hice:

Usa un spinlock simple con un try_lockCuando un hilo no puede probar try_lock, en lugar de esperar, llenan una cola (que no se comparte con otros hilos) y continúanCuando un subproceso obtiene un bloqueo, actualiza el búfer con el resultado actual, pero también con los resultados almacenados en la cola (procesa su cola)La descarga del búfer se hizo mucho más eficiente: la parte de bloqueo solo intercambia dos punteros.

Respuestas a la pregunta(2)

Su respuesta a la pregunta