Разница в скорости блокировки мьютекса внутри и снаружи петли

Я запутался в скорости, отличающейся между использованием mutex lock() и unlock() внутри и снаружи цикла for. Я получил значение глобальной переменной и функцию, которая увеличивает его в 1000000 раз. Эта функция запускается параллельно 5 потоками. Я измерил прошедшее время и получил следующие результаты:

    mutex.lock();
    for(int i = 0; i < 1000000; i++)
    {
        value++;
    }
    mutex.unlock();

0,160921 секунд

а также:

    for(int i = 0; i < 1000000; i++)
    {        
        mutex.lock();
        value++;
        mutex.unlock();
    }

2,10521 секунды

Я предполагаю, что со вторым расположением внутреннего мьютекса управление слишком хорошо, и много времени тратится между переключением потоков? или есть что-то еще?

1 ответ

Блокировка и разблокировка мьютекса занимает некоторое время. В частности, это занимает много времени больше, чем увеличение целого числа. Ваш второй пример - просто тестирование скорости блокировки / разблокировки, а также добавление накладных расходов на переключение задач, потому что в любой точке, где мьютекс разблокирован, другой поток может вступить во владение.

И во-первых, компилятор может просто заменить цикл одним добавлением. И поскольку мьютекс полностью покрывает всю функцию потока, параллельного выполнения нет; все потоки, кроме одного, просто блокируются до тех пор, пока цикл одного не будет завершен, что означает, что код эквивалентен простому циклу пять раз подряд в одном потоке.

Это имеет мало общего с мелкозернистой блокировкой. Эти стратегии заключаются в том, есть ли у вас несколько блокировок, охватывающих много ресурсов, или много блокировок, охватывающих несколько ресурсов. У вас есть только один ресурс (глобальный int), и поэтому вы не можете принять решение.

Вместо этого речь идет о том, стоит ли блокировать мьютекс на короткое время, оставляя его открытым в остальное время для выполнения другими потоками, или блокируйте его на более длительные периоды, чтобы избежать издержек, но уменьшая параллелизм. Однако, поскольку ваши потоки ничего не делают, кроме доступа к защищенному ресурсу, "остального времени" не существует. Ваша задача (с приращением целого числа 5000000 раз) не имеет изначально присущего ей параллелизма и, следовательно, не может использовать несколько потоков.

Другие вопросы по тегам