Мое мнение таково, что оптимальное «число оборотов» для лучшей производительности приложения слишком зависит от аппаратного обеспечения, чтобы оно было важной частью кроссплатформенного API, и вам, вероятно, следует просто использовать мьютексы (в posix, pthread_mutex_init
/ destroy
/ lock
/ trylock
) или спин-блокировки (pthread_spin_init
/ destroy
/ lock
/ trylock
). Обоснование следует.
Какой смысл в счетчике спинов? По сути, если владелец блокировки работает одновременно с потоком, пытающимся получить блокировку, то владелец блокировки может снять блокировку достаточно быстро, чтобы вызывающая программа EnterCriticalSection могла избежать отказа от управления процессором при получении блокировки, улучшая производительность этого потока и избегая издержки переключения контекста. Две вещи:
1: очевидно, что это зависит от владельца блокировки, работающего параллельно потоку, пытающемуся получить блокировку. Это невозможно на одном исполнительном ядре, и почти наверняка Microsoft воспринимает это число как 0 в таких средах. Даже с несколькими ядрами вполне возможно, что владелец блокировки не работает, когда другой поток пытается получить блокировку, и в таких случаях оптимальное число вращений (для этой попытки) все еще равно 0.
2: при одновременном выполнении оптимальное число вращений по-прежнему зависит от оборудования. Разным процессорам потребуется разное количество времени для выполнения одинаковых операций. У них разные наборы команд (у ARM, с которым я работаю больше, нет инструкции по целочисленному разделению), разные размеры кеша, у ОС будут разные страницы в памяти ... Уменьшение числа вращений может занять разное время на архитектура хранения данных, чем архитектура, в которой арифметические инструкции могут напрямую обращаться к памяти. Даже на одном и том же процессоре одна и та же задача займет различное количество времени, в зависимости (по крайней мере) от содержимого и организации кэша памяти.
Если оптимальное число вращений при одновременном выполнении бесконечно, то функции pthread_spin_*
должны делать то, что вам нужно. Если это не так, используйте функции pthread_mutex_*
.