Разница в скорости блокировки мьютекса внутри и снаружи петли
Я запутался в скорости, отличающейся между использованием 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 раз) не имеет изначально присущего ей параллелизма и, следовательно, не может использовать несколько потоков.