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