我们观察到,在linux futexes竞争时,系统在旋转锁定上花费了大量时间。 我们注意到,不直接使用futexes也是一个问题,在调用malloc/free、rand、glib mutex和其他调用futex的系统/库调用时也存在问题。 ANY有办法摆脱这种行为吗? futex争用时提高系统CPU利用率
您使用的是内核2.6.32-279.9.1.el6.x86_64的CentOS 6.3。 我也尝试了直接从kernel.org下载的最新稳定内核3.6.6。
原本,配备16gb ram的24核心服务器出现了问题。 这个过程有700个线程。 根据使用“perf记录”收集的数据,旋转锁由__lll_lock_wait_private和__lll_unlock_wake_private调用在gdb中停止进程时,调用_ lll _ lock _ wait _ private _ lll _ unlock _ wake _ private会追溯到是由malloc和free创建的。
我试图减少这个问题,所以写了简单的程序。 那表明确实是导致螺杆锁定问题的futexes。
启动八个线程,并对每个线程执行以下操作:
//.
staticgmutex * lmethodmutex=g _ mutex _ new (;
为wile (真)
{
静态guint 64 I=0;
g_mutex_lock(lmethodmutex;
//performanyoperationintheuserspacethatneedstobeprotected。
//theoperationitselfisnotimportant.it ' sthetakingandreleasing
//of the mutex that matters。
I;
g_mutex_unlock(lmethodmutex;
}
//.
我在8核的机器上运行这个,使用大量的RAM。
使用“上部”,发现机器空闲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%的自旋锁定时间似乎太多了,尤其是在这个CPU时间需要做其他有用的工作时。
1
你可能想谈谈你想看的行为。 我觉得这个不完全清楚。
0
使用互斥锁或futex同时增加变量(如上面的示例所示)有点愚蠢。 这是因为可以直接使用原子的增量,高效地进行50~500倍。 在“真实”的代码中,也就是在实际做了某件事的代码中,我们发现拥挤和浪费的时间浪费在了旋转上,而不是不可忽视的细节上。 实时代码不会同时争夺六个线程的锁定。
1
首先,即使没有直接从用户代码中调用futexes,我也注意到这是一个问题,因为这是一个malloc/free、rand、glib mutex调用和调用futex的其他系统/库调用问题说明中提供的代码片段仅用于指示问题的发生,而不表示任何有用的活动。 实际上,互斥调用之间的代码可以是任何用户代码。