Wie misst man Mutex-Konflikte?

Lesezeit: 4 Minuten

Benutzer-Avatar
Luis Oliveira

Ich habe einen Thread-Code, der PThreads unter Linux verwendet, der, wie ich vermute, unter übermäßigen Sperrkonflikten leidet. Welche Tools stehen mir zur Verfügung, um dies zu messen?

Solaris hat DTrace und plockstat. Gibt es etwas ähnliches unter Linux? (Ich weiß von einer kürzlich erschienenen DTrace-Portierung für Linux, aber sie scheint noch nicht bereit für die Hauptsendezeit zu sein.)

mutrace ist das Werkzeug:
http://0pointer.de/blog/projects/mutrace.html

Es ist einfach zu bauen, zu installieren und zu verwenden.

  • Der Quellcode scheint dort nicht mehr verfügbar zu sein, aber er ist hier: github.com/dbpercona/mutrace

    – Lukasz Czerwinski

    18. März 2016 um 0:59 Uhr

Benutzer-Avatar
Luis Oliveira

Nachdem ich mit SystemTap nicht viel Glück hatte, beschloss ich, trotz des Fehlens eines plockstat-Anbieters mit einigem Erfolg zu versuchen, die DTrace-Linux-Portierung zu verwenden. Das folgende DTrace-Skript ist nicht ganz a plockstat Ersatz, aber es gelang mir, mir einige der Informationen zu zeigen, nach denen ich gesucht hatte.

#!/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;
}

Hier ist ein Beispiel, das das obige DTrace-Skript verwendet, um die in FUTEX_WAIT verbrachte Zeit für ein einfaches Testprogramm daraus zu messen DTrace-Artikel.

$ ./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        

Definitiv nicht großartig, aber zumindest ist es ein Ausgangspunkt.

Die neuesten Versionen von Valgrind verfügen über Sperrkonflikt- und Sperrvalidierungstools:

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

Was großartig ist, wenn Sie das Problem unter Valgrind erzeugen können (es wirkt sich auf die Laufzeitgeschwindigkeit des Codes aus) und über genügend Speicher verfügen, um Valgrind auszuführen.

Für andere Anwendungen wird das härtere Linux Trace Toolkit NG empfohlen:

http://ltt.polymtl.ca/

Gruß, Gilad

  • Danke für deinen Vorschlag, aber Valgrind mag die Anwendung, die ich teste, wirklich nicht und kotzt sehr schnell.

    – Luis Oliveira

    9. August 2009 um 15:46 Uhr

  • Dieser Link ist tot. Ich finde lttng.org ist heutzutage der richtige Ort, um nachzusehen.

    – Itkovian

    22. Januar 2020 um 8:35 Uhr

Die neueste Version von systemtap enthält viele Beispielskripte. Eine davon scheint ein guter Ausgangspunkt zu sein, um Ihnen bei der Erfüllung Ihrer Aufgabe zu helfen:

#! /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
  thread_blocktime
}

probe syscall.futex.return {  
  t = tid()
  ts = thread_blocktime
  if (ts) {
    elapsed = gettimeofday_us() - ts
    lock_waits[pid(), thread_thislock
    delete thread_blocktime
    delete thread_thislock
  }
}

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]))
}

Ich habe zuvor versucht, etwas Ähnliches mit einem MySQL-Prozess zu diagnostizieren, und eine Ausgabe ähnlich der folgenden mit dem obigen Skript beobachtet:

mysqld[3991] lock 0x000000000a1589e0 contended 45 times, 3 avg us
mysqld[3991] lock 0x000000004ad289d0 contended 1 times, 3 avg us

Während das obige Skript Informationen zu allen Prozessen sammelt, die auf dem System ausgeführt werden, wäre es recht einfach, es so zu ändern, dass es nur mit einem bestimmten Prozess oder einer bestimmten ausführbaren Datei funktioniert. Beispielsweise könnten wir das Skript so ändern, dass es ein Prozess-ID-Argument verwendet, und die Sonde beim Eingeben des futex-Aufrufs so ändern, dass sie folgendermaßen aussieht:

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
    thread_blocktime
  }
}

Offensichtlich können Sie das Skript auf viele Arten ändern, um es an das anzupassen, was Sie tun möchten. Ich möchte Sie ermutigen, sich die verschiedenen Beispielskripte für SystemTap anzusehen. Sie sind wahrscheinlich der beste Ausgangspunkt.

In Ermangelung von DTrace ist Ihre beste Wahl wahrscheinlich SystemTap. Hier ist ein positives Schreiben.

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

  • Ich fürchte, dieser Blogbeitrag erwähnt ausdrücklich, dass er für die Messung von Sperrkonflikten nicht sehr nützlich war.

    – Luis Oliveira

    8. August 2009 um 20:02 Uhr

  • In Kommentaren sagt er, er habe jedoch nicht versucht, Symbole aufzulösen.

    – Eugen

    8. August 2009 um 20:27 Uhr

  • Ich fürchte, dieser Blogbeitrag erwähnt ausdrücklich, dass er für die Messung von Sperrkonflikten nicht sehr nützlich war.

    – Luis Oliveira

    8. August 2009 um 20:02 Uhr

  • In Kommentaren sagt er, er habe jedoch nicht versucht, Symbole aufzulösen.

    – Eugen

    8. August 2009 um 20:27 Uhr

1335710cookie-checkWie misst man Mutex-Konflikte?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy