2009-08-08 20 views
22

मेरे पास लिनक्स पर PThreads का उपयोग करके कुछ थ्रेड कोड है, मुझे संदेह है कि अत्यधिक लॉक विवाद से पीड़ित है। इसे मापने के लिए मेरे लिए कौन से टूल्स उपलब्ध हैं?म्यूटेक्स विवाद को मापने के लिए कैसे करें?

सोलारिस में डीटी्रेस और प्लॉकस्टैट है। क्या लिनक्स पर कुछ समान है?

उत्तर

1

DTrace के अभाव में (मैं लिनक्स के लिए हाल ही में एक DTrace बंदरगाह के बारे में पता है, लेकिन यह अभी तक प्राइम टाइम के लिए तैयार होने के लिए प्रतीत नहीं होता।), अपने सबसे अच्छे शर्त शायद SystemTap है। यहां एक सकारात्मक लिखना है।

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

+0

मुझे डर है कि ब्लॉग पोस्ट स्पष्ट रूप से उल्लेख करता है कि यह लॉक विवाद को मापने के लिए बहुत उपयोगी नहीं था। –

+2

टिप्पणियों में उन्होंने कहा कि उन्होंने प्रतीकों को हल करने का प्रयास नहीं किया था। – Eugene

+0

अच्छा बिंदु, मैं इसे आज़मा दूंगा। –

4

SystemTap के साथ बहुत किस्मत नहीं होने के बाद, मैं कोशिश करते हैं और कुछ सफलता DTrace Linux port उपयोग करते हैं, एक plockstat प्रदाता की कमी के बावजूद का फैसला किया। निम्नलिखित डीटी्रेस स्क्रिप्ट काफी 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   

निश्चित रूप से महान नहीं है, लेकिन कम से कम यह एक प्रारंभिक बिंदु है।

4

valgrind नवीनतम संस्करण एक ताला विवाद और लॉक सत्यापन उपकरण है:

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

कौन महान है अगर आप वेलग्रिंड के तहत इस मुद्दे का उत्पादन कर सकते हैं (यह समय की गति कोड रन प्रभाव) और चलाने के लिए पर्याप्त स्मृति वेलग्रिंड।

अन्य उपयोगों के लिए अधिक हार्ड कोर लिनक्स ट्रेस टूलकिट एनजी की सिफारिश की है:

http://ltt.polymtl.ca/

चीयर्स, गिलाड

+0

आपके सुझाव के लिए धन्यवाद लेकिन वाल्ग्रिंड वास्तव में उस एप्लिकेशन को पसंद नहीं करता है जिसे मैं परीक्षण कर रहा हूं और वास्तव में बारफ़्स जल्दी से। –

4

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 

ऊपर स्क्रिप्ट सिस्टम पर चलने वाले सभी प्रक्रियाओं के बारे में जानकारी एकत्र करता है, यह एक निश्चित प्रक्रिया या निष्पादन पर ही काम करने के लिए इसे संशोधित करने के लिए काफी आसान होगा। उदाहरण के लिए, हम एक प्रक्रिया आईडी तर्क लेते हैं और तरह देखने के लिए 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() 
    } 
} 

जाहिर है, तुम क्या आप चाहते हैं के अनुरूप करने के तरीकों में से स्क्रिप्ट बहुत संशोधित कर सकते कर। मैं आपको सिस्टमटैप के लिए विभिन्न उदाहरण स्क्रिप्ट्स पर नज़र रखने के लिए प्रोत्साहित करता हूं। वे शायद सबसे अच्छा प्रारंभिक बिंदु हैं।

13

mutrace उपकरण है: http://0pointer.de/blog/projects/mutrace.html

इसके निर्माण को स्थापित करने और उपयोग करने के लिए आसान।

+0

स्रोत कोड अब और उपलब्ध नहीं प्रतीत होता है, लेकिन यह यहां है: https://github.com/dbpercona/mutrace –

+0

लेनार्ट का कोड यहां पाया जा सकता है: http://git.0pointer.net/mutrace.git/ – stsquad

संबंधित मुद्दे