【问题标题】:How to measure mutex contention?如何衡量互斥量争用?
【发布时间】:2010-11-17 23:52:14
【问题描述】:

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

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

【问题讨论】:

    标签: c linux pthreads dtrace


    【解决方案1】:

    mutrace 是工具: http://0pointer.de/blog/projects/mutrace.html

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

    【讨论】:

    【解决方案2】:

    最新版本的 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 的各种示例脚本。它们可能是最好的起点。

    【讨论】:

      【解决方案3】:

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

      http://valgrind.org/docs/manual/drd-manual.html

      如果您可以在 Valgrind 下产生问题(它会影响代码运行时速度)并且有足够的内存来运行 Valgrind,那就太好了。

      其他用途,推荐更硬核的Linux Trace Toolkit NG:

      http://ltt.polymtl.ca/

      干杯, 吉拉德

      【讨论】:

      • 感谢您的建议,但 valgrind 真的不喜欢我正在测试的应用程序,而且很快就会失败。
      • 该链接已失效。我认为lttng.org 是现在看的正确位置。
      【解决方案4】:

      在使用 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        
      

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

      【讨论】:

        【解决方案5】:

        在没有 DTrace 的情况下,您最好的选择可能是 SystemTap。这是一篇积极的文章。

        http://davidcarterca.wordpress.com/2009/05/27/systemtap/

        【讨论】:

        • 恐怕那篇博文明确提到它对于测量锁争用不是很有用。
        • 在 cmets 中他说他没有尝试解析符号。
        猜你喜欢
        • 1970-01-01
        • 2012-07-27
        • 2012-09-01
        • 1970-01-01
        • 2016-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-14
        相关资源
        最近更新 更多