我有一些使用Linux上的PThreads的線程代碼,我懷疑是遭受了過度的鎖爭用。我有什麼工具可以衡量這一點?如何衡量互斥量爭用?
Solaris有DTrace和plockstat。 Linux上有類似的東西嗎? (我知道最近用於Linux的DTrace端口,但它似乎還沒有準備好黃金時間。)
我有一些使用Linux上的PThreads的線程代碼,我懷疑是遭受了過度的鎖爭用。我有什麼工具可以衡量這一點?如何衡量互斥量爭用?
Solaris有DTrace和plockstat。 Linux上有類似的東西嗎? (我知道最近用於Linux的DTrace端口,但它似乎還沒有準備好黃金時間。)
在沒有DTrace的情況下,您最好的選擇可能是SystemTap。這是一個積極的寫作。
不具有的SystemTap多少運氣之後,我決定嘗試,使用DTrace Linux port取得了一些成功,儘管缺少plockstat提供的。以下DTrace腳本並不完全代替plockstat,但它能夠向我展示一些我之後的信息。
#!/usr/sbin/dtrace -s
/* Usage: ./futex.d '"execname"' */
long total;
END
{
printf("total time spent on futex(): %ldms\n", total);
}
/* arg1 == 0 means FUTEX_WAIT */
syscall::futex:entry
/execname == $1 && arg1 == 0/
{
self->start = timestamp;
}
syscall::futex:return
/self->start/
{
this->elapsed = (timestamp - self->start)/1000000;
@[execname] = quantize(this->elapsed);
total += this->elapsed;
self->start = 0;
}
下面是使用上述DTrace腳本以測量從該DTrace article在FUTEX_WAIT花費一個簡單的測試程序的時間的例子。
$ ./futex.d '"mutex-test"'
dtrace: script './futex.d' matched 3 probes
^C
CPU ID FUNCTION:NAME
1 2 :END total time spent on futex(): 11200ms
mutex-test
value ------------- Distribution ------------- count
128 | 0
256 |@@@@@@@@@@@@@@@@@@@@ 1
512 | 0
1024 | 0
2048 | 0
4096 | 0
8192 |@@@@@@@@@@@@@@@@@@@@ 1
16384 | 0
絕對不是很好,但至少它是一個起點。
Valgrind的最新版本,有鎖爭用,鎖驗證工具:
http://valgrind.org/docs/manual/drd-manual.html
這是偉大的,如果你能生產Valgrind的下問題(它影響的代碼運行時的速度),並有足夠的內存運行Valgrind的。
作其他用途,更硬Linux核心跟蹤工具包NG建議:
乾杯, 吉拉德
感謝您的建議,但valgrind真的不喜歡我測試的應用程序和真正快速的barf。 – 2009-08-09 15:46:08
SystemTap的最新版本帶有很多example scripts。其中特別是似乎將服務器作爲一個很好的起點,幫助你完成你的任務:
#! /usr/bin/env stap
global thread_thislock
global thread_blocktime
global FUTEX_WAIT = 0
global lock_waits
global process_names
probe syscall.futex {
if (op != FUTEX_WAIT) next
t = tid()
process_names[pid()] = execname()
thread_thislock[t] = $uaddr
thread_blocktime[t] = gettimeofday_us()
}
probe syscall.futex.return {
t = tid()
ts = thread_blocktime[t]
if (ts) {
elapsed = gettimeofday_us() - ts
lock_waits[pid(), thread_thislock[t]] <<< elapsed
delete thread_blocktime[t]
delete thread_thislock[t]
}
}
probe end {
foreach ([pid+, lock] in lock_waits)
printf ("%s[%d] lock %p contended %d times, %d avg us\n",
process_names[pid], pid, lock, @count(lock_waits[pid,lock]),
@avg(lock_waits[pid,lock]))
}
我試圖診斷與MySQL進程先前類似類似於使用上面的腳本下面的內容並觀察輸出:
mysqld[3991] lock 0x000000000a1589e0 contended 45 times, 3 avg us
mysqld[3991] lock 0x000000004ad289d0 contended 1 times, 3 avg us
雖然上面的腳本收集的系統上運行的所有進程的信息,這將是很容易將它修改爲只工作在某個進程或可執行文件。例如,我們可以修改腳本以一個進程ID參數,並修改進入futex的電話看起來像探頭:
probe begin {
process_id = strtol(@1, 10)
}
probe syscall.futex {
if (pid() == process_id && op == FUTEX_WAIT) {
t = tid()
process_names[process_id] = execname()
thread_thislock[t] = $uaddr
thread_blocktime[t] = gettimeofday_us()
}
}
很明顯,你可以修改腳本很多方法來適應你想要什麼做。我鼓勵你看看SystemTap的各種示例腳本。他們可能是最好的起點。
mutrace是工具: http://0pointer.de/blog/projects/mutrace.html
它易於構建,安裝和使用。
源代碼似乎不再可用,但它在這裏:https://github.com/dbpercona/mutrace – 2016-03-18 00:59:04
Lennart的代碼可以在http://git.0pointer.net/mutrace.git/找到。 – stsquad 2016-11-03 16:25:46
恐怕博客文章明確提到它對衡量鎖爭用並不是很有用。 – 2009-08-08 20:02:29
在評論中他說他沒有嘗試解析符號。 – Eugene 2009-08-08 20:27:19
好點,我會試試看。 – 2009-08-08 20:39:53