Я заметил, что когда futexes linux утверждаются, система тратит A LOT времени в спин-блоки. Я заметил, что это проблема, даже когда futexes не используются напрямую, но также при вызове malloc/free, rand, glib-мьютекс-вызовы и других вызовов системных/библиотечных, которые вызывают вызовы futex. Есть ли способ избавиться от этого поведения?
Я использую CentOS 6.3 с ядром 2.6.32-279.9.1.el6.x86_64. Я также пробовал самое последнее стабильное ядро 3.6.6, загруженное непосредственно с kernel.org.
Первоначально проблема возникла на 24-ядерном сервере с ОЗУ 16 ГБ. Процесс имеет 700 потоков. Данные, собранные с помощью "персидской записи", показывают, что спин-блокировка вызывается из futex, вызванного из __lll_lock_wait_private и __lll_unlock_wake_private, и убирает 50% процессорного времени. Когда я остановил процесс с помощью gdb, обратные трассы показали, что вызовы __lll_lock_wait_private __lll_unlock_wake_private сделаны из malloc и бесплатны.
Я пытался уменьшить проблему, поэтому я написал простую программу, которая действительно показывает фьютекс, вызывающий проблему спин-блокировки.
Начните 8 потоков, каждый поток выполнит следующее:
//...
static GMutex *lMethodMutex = g_mutex_new ();
while (true)
{
static guint64 i = 0;
g_mutex_lock (lMethodMutex);
// Perform any operation in the user space that needs to be protected.
// The operation itself is not important. It the taking and releasing
// of the mutex that matters.
++i;
g_mutex_unlock (lMethodMutex);
}
//...
Я запускаю это на 8-ядерном компьютере с большим количеством ОЗУ.
Используя "верх", я заметил, что машина 10% в режиме ожидания, 10% в пользовательском режиме и 90% в системном режиме.
Используя "perf top", я заметил следующее:
50.73% [kernel] [k] _spin_lock
11.13% [kernel] [k] hpet_msi_next_event
2.98% libpthread-2.12.so [.] pthread_mutex_lock
2.90% libpthread-2.12.so [.] pthread_mutex_unlock
1.94% libpthread-2.12.so [.] __lll_lock_wait
1.59% [kernel] [k] futex_wake
1.43% [kernel] [k] __audit_syscall_exit
1.38% [kernel] [k] copy_user_generic_string
1.35% [kernel] [k] system_call
1.07% [kernel] [k] schedule
0.99% [kernel] [k] hash_futex
Я ожидаю, что этот код потратит некоторое время на спин-блокировку, поскольку код futex должен получить очередь ожидания futex. Я также ожидал, что код потратит некоторое время в системе, поскольку в этом фрагменте кода в пользовательском пространстве работает очень мало кода. Однако 50% времени, затрачиваемого на спин-блокировку, кажется чрезмерным, особенно когда это время процессора требуется для выполнения другой полезной работы.