Вы правы сделать безотносительно работ.
..., пока Вы понимаете, что может быть цена для оплаты позже. Это кажется, что Вы думаете об этом так или иначе.
Вещи проверить:
Видят мои другие сообщения на общих подсказках по производительности:
After not having much luck with SystemTap, I decided to try and use the DTrace Linux port with some success, despite the lack of a plockstat provider. The following DTrace script is not quite a plockstat replacement but it managed to show me some of the information I was after.
#!/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;
}
Here's an example using the above DTrace script to measure time spent in FUTEX_WAIT for a simple test program from this DTrace article.
$ ./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
Definitely not great, but at least it's a starting point.
В последних версиях valgrind есть инструменты блокировки и проверки блокировок:
http://valgrind.org/docs/manual/drd-manual.html
Что отлично, если вы может вызвать проблему в Valgrind (это влияет на скорость выполнения кода) и иметь достаточно памяти для запуска Valgrind.
Для других целей рекомендуется более сложный Linux Trace Toolkit NG:
Ура, Гилад
В отсутствие DTrace лучшим вариантом, вероятно, будет SystemTap . Вот положительный отзыв.
mutrace - это инструмент: http://0pointer.de/blog/projects/mutrace.html
Его легко собрать, установить и использовать.
Последняя версия systemtap поставляется с множеством примеров сценариев . Один, в частности, кажется, что это будет сервер в качестве хорошей отправной точки для помощи вам в выполнении вашей задачи:
#! /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
Хотя приведенный выше сценарий собирает информацию обо всех процессах, запущенных в системе, было бы довольно легко изменить его, чтобы он работал только с определенным процессом или исполняемым файлом. Например, мы могли бы изменить скрипт, чтобы он принимал аргумент идентификатора процесса и модифицировал зонд при входе в вызов фьютекса, чтобы он выглядел так:
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. Вероятно, они являются лучшей отправной точкой.