【问题标题】:Python asynchronously increment the same variable to boost performance?Python异步增加相同的变量以提高性能?
【发布时间】:2021-08-05 13:29:12
【问题描述】:

我如何使用多个线程并行地同时增加同一个变量,从而将总时间减少到原始同步过程的倍数?

例子:

num = 0                     
def incrementer():               
    for i in range(100):    
        global num
        num += 1            
for i in range(100):        
    th=Thread(target=incrementer)
    th.start()              
num                         

上面的代码确实给出了预期的结果(10000),但是所花费的时间比同步方法要长得多:

In [114]: %%timeit                                                     
     ...: num = 0                                                      
     ...: def incrementer():                                                
     ...:     for i in range(100):                                     
     ...:         global num                                           
     ...:         num += 1                                             
     ...: for i in range(100):                                         
     ...:     th=Thread(target=incrementer)                                 
     ...:     th.start()                                               
25.3 ms ± 2.27 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [113]: %%timeit                                                     
     ...: num = 0                                                      
     ...: for i in range(10000):                                       
     ...:     num += 1                                                 
596 µs ± 84.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

我预计多线程方法将花费同步方法的 1% 的时间...

我怎样才能使异步方法花费同步方法所用时间的 n 分之一来完成 n 个线程,或者这显然是不可能的?

【问题讨论】:

  • 这能回答你的问题吗? python multi-threading slower than serial?
  • Python 不做真正的线程,除非你使用类似multiprocessing 包的东西。此外,您的基准测试包括设置线程的成本,这不一定是微不足道的,我怀疑它会主导您的结果。作为旁注,您的代码不是线程安全的。整数写入在 Python 中是原子的,但增量是两个操作(读取和写入),并且可以在两者之间中断。
  • 实例化新线程的运行时开销远远超过函数执行所花费的时间

标签: python python-3.x multithreading asynchronous


【解决方案1】:

多线程性能提升并不像您想象的那样线性。

假设您有一个 4 核 CPU (nc=4),从单线程 (t=1) 到 4 线程 (t=4) 应该会显示总体计算时间有所减少。 如果您有一个 4 核 CPU,您可能预计计算时间会减少 75%,但在现实世界中,仍然需要做一些工作来保持操作系统运行。

拥有比物理内核更多的线程 (t>nc),充其量只能提供与匹配这些值 (t=nc) 相同的性能,但在现实世界中,使用 t>>nc 管理资源会可能实际上运行速度有点慢。

接下来,您的方法是使用由所有线程更新的单个计数器,这会增加复杂性,因为您需要互斥锁/信号量/等。确保计数器更新按预期运行,多方读取/写入它 - 方越多,这就越难,而且,你猜对了,又一次性能下降。

我建议将您的问题空间划分为线程数(t=nc,如果您在上面阅读)这样(例如)threadA 处理 0-24threadB: 25-49threadC 50-74 和 @987654325 @ - 这样他们就不需要互相交谈,因为每个人都在处理自己的问题空间。

tl;博士:

  • 多线程时,几乎没有任何优势可以超越 t=nc,但在功能上,您甚至可能希望在 t=(nc-1) 处停下来以留出一些 CPU您的操作系统/等的时间。
  • 线程同步需要谨慎;尝试在将作业发送到线程之前将饼图切成t 块。

【讨论】:

    猜你喜欢
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 2021-02-22
    • 2013-01-10
    • 1970-01-01
    • 2017-10-13
    • 2021-08-16
    相关资源
    最近更新 更多