Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何度量互斥争用?_C_Linux_Pthreads_Dtrace - Fatal编程技术网

C 如何度量互斥争用?

C 如何度量互斥争用?,c,linux,pthreads,dtrace,C,Linux,Pthreads,Dtrace,我有一些在Linux上使用PThreads的线程化代码,我怀疑这些代码正遭受过度的锁争用。我可以使用什么工具来衡量这一点 Solaris有DTrace和plockstat。Linux上有类似的东西吗?(我知道最近有一个针对Linux的DTrace端口,但它似乎还没有准备好进入黄金时段。)如果没有DTrace,您最好的选择可能是。这是一篇积极的评论 在SystemTap方面运气不佳之后,我决定尝试使用,并取得了一些成功,尽管缺少plockstat提供程序。下面的DTrace脚本并不是一个很好的替代

我有一些在Linux上使用PThreads的线程化代码,我怀疑这些代码正遭受过度的锁争用。我可以使用什么工具来衡量这一点


Solaris有DTrace和plockstat。Linux上有类似的东西吗?(我知道最近有一个针对Linux的DTrace端口,但它似乎还没有准备好进入黄金时段。)

如果没有DTrace,您最好的选择可能是。这是一篇积极的评论


在SystemTap方面运气不佳之后,我决定尝试使用,并取得了一些成功,尽管缺少plockstat提供程序。下面的DTrace脚本并不是一个很好的替代品,但它成功地向我展示了我想要的一些信息

#!/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脚本测量FUTEX_等待一个简单测试程序的时间的示例


肯定不是很好,但至少这是一个起点。

valgrind最新版本具有锁争用和锁验证工具:

如果您可以在Valgrind下生成问题(它会影响代码运行时的速度),并且有足够的内存运行Valgrind,这将是非常好的

对于其他用途,建议使用更为核心的Linux跟踪工具包NG:

干杯,
Gilad

最新版本的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]))
}
虽然上面的脚本收集系统上运行的所有进程的信息,但是修改它以仅在某个进程或可执行文件上工作是非常容易的。例如,我们可以将脚本更改为采用进程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是一种工具:


它易于构建、安装和使用。

我担心这篇博客文章明确提到它对于测量锁争用不是很有用。在评论中,他说他没有尝试解析符号。谢谢你的建议,但是valgrind确实不喜欢我正在测试的应用程序,而且很快就会呕吐。这个链接已经失效了。我认为现在应该去看看。那里似乎不再有源代码,但它在这里:
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()
  }
}