Python 2.6 vs 2.7多线程性能问题(futex)

Ano*_*oop 7 python linux multithreading futex

我有一个简单的Monte-Carlo Pi计算程序.我尝试在2个不同的盒子上运行它(相同的硬件,内核版本略有不同).我发现在一种情况下(两倍的时间)性能显着下降.没有线程,性能大致相同.对程序的分析执行表明,较慢的程序每个futex调用花费较少的时间.

  • 这与任何内核参数有关吗?
  • CPU标志会影响futex性能吗?/ proc/cpuinfo表示cpu标志略有不同.
  • 这有点与python版本有关吗?

Linux(3.10.0-123.20.1(Red Hat 4.4.7-16))Python 2.6.6

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
99.69   53.229549           5  10792796   5385605 futex

Profile Output
============== 
256 function calls in 26.189 CPU seconds

Ordered by: standard name

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
   39   26.186    0.671   26.186    0.671 :0(acquire)
Run Code Online (Sandbox Code Playgroud)

Linux(3.10.0-514.26.2(Red Hat 4.8.5-11))Python 2.7.5

 % time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 99.69   94.281979           8  11620358   5646413 futex

Profile Output
==============
259 function calls in 53.448 seconds

Ordered by: standard name

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 38   53.445    1.406   53.445    1.406 :0(acquire)
Run Code Online (Sandbox Code Playgroud)

测试程序

import random
import math
import time
import threading
import sys
import profile

def find_pi(tid, n):
    t0 = time.time()
    in_circle = 0
    for i in range(n):
        x = random.random()
        y = random.random()

        dist = math.sqrt(pow(x, 2) + pow(y, 2))
        if dist < 1:
            in_circle += 1

    pi = 4.0 * (float(in_circle)/float(n))
    print 'Pi=%s - thread(%s) time=%.3f sec' % (pi, tid, time.time() - t0)
    return pi

def main():
        if len(sys.argv) > 1:
            n = int(sys.argv[1])
        else:
            n = 6000000

        t0 = time.time()
        threads = []
        num_threads = 5
        print 'n =', n
        for tid in range(num_threads):
            t = threading.Thread(target=find_pi, args=(tid,n,))
            threads.append(t)
            t.start()

        for t in threads:
                t.join()

#main()
profile.run('main()')
#profile.run('find_pi(1, 6000000)')
Run Code Online (Sandbox Code Playgroud)

Mic*_*ski -1

我认为你无法得到严格的答案。

Futex是和内核相关的东西。是手册页。

tl;dr - 例如 - 线程由内核调度,如果高优先级线程被低优先级线程阻塞,则存在所谓的优先级反转。因此观察到的下降可能是由于内核标志造成的。另一点是获取时间 - 进入内核以获取实时值。

另一方面,您只启动了一个线程,因此这应该不是问题。你的线程不会干扰,所以它不应该是类似锁定的东西。我看到acquire被调用,但查看所花费的时间表明它是关于在最后等待线程的 join() 。

您能否执行测试(假设执行 50 次)并提供统计数据?这需要一个小时,但一分钟的测试几乎可以受到任何因素的影响。

顺便说一句,你错过了(进口):

import random
import math
Run Code Online (Sandbox Code Playgroud)