ホームページ  >  記事  >  バックエンド開発  >  マルチスレッドがシングルスレッドよりも高速であるというのは本当ですか?

マルチスレッドがシングルスレッドよりも高速であるというのは本当ですか?

coldplay.xixi
coldplay.xixi転載
2020-11-09 17:11:403082ブラウズ

pyrhon ビデオ チュートリアル コラムでは、マルチスレッドがシングルスレッドよりも本当に速いかどうかを紹介します。

マルチスレッドがシングルスレッドよりも高速であるというのは本当ですか?

実際、Python マルチスレッドに関するもう 1 つの非常に重要なトピックは、

GIL(Globalインタープリター ロック、グローバル インタープリター ロック)。

マルチスレッドは必ずしも単一スレッドより高速であるとは限りません

Python では、マルチプロセス、マルチスレッド、およびマルチコルーチンを通じてマルチタスクを実現できます。マルチスレッドはシングルスレッドよりも必ずしも高速なのでしょうか?

以下では、コードの一部を使用して私自身の見解を証明します。

'''
@Author: Runsen
@微信公众号: Python之王
@博客: https://blog.csdn.net/weixin_44510615
@Date: 2020/6/4
'''import threading, timedef my_counter():
    i = 0
    for _ in range(100000000):
        i = i+1
    return Truedef main1():
    start_time = time.time()    for tid in range(2):
        t = threading.Thread(target=my_counter)
        t.start()
        t.join()  # 第一次循环的时候join方法引起主线程阻塞,但第二个线程并没有启动,所以两个线程是顺序执行的

    print("单线程顺序执行total_time: {}".format(time.time() - start_time))def main2():
    thread_ary = {}
    start_time = time.time()    for tid in range(2):
        t = threading.Thread(target=my_counter)
        t.start()
        thread_ary[tid] = t    for i in range(2):
        thread_ary[i].join()  # 两个线程均已启动,所以两个线程是并发的

    print("多线程执行total_time: {}".format(time.time() - start_time))if __name__ == "__main__":
    main1()
    main2()复制代码
実行結果

单线程顺序执行total_time: 17.754502773284912多线程执行total_time: 20.01178550720215复制代码
結果をランダムに取得できると言うかもしれないので、はっきりと確認するためにスクリーンショットを撮ったほうがよいでしょう

このとき、私は「マシンに何か問題があるのだろうか?」と疑問に思いました。本質的に、Python のスレッドは失敗しており、並列コンピューティングでは役割を果たしません。

Python のスレッドは、基礎となるオペレーティング システムのスレッドをカプセル化します。Linux システムでは、

Pthread (フルネームは POSIX Thread) ですが、Windows システムでは、それは Pthread Windows Thread

です。さらに、Python のスレッドは、実行時期の調整、メモリ リソースの管理、割り込みの管理など、オペレーティング システムによって完全に管理されます。

GIL は Python の機能ではありません

GIL の概念は簡単な文で説明できます。つまり、いつでも、スレッドの数に関係なく、単一のCPython インタープリターは 1 バイトのコード

のみを実行できます。この定義に関する注意点:

最初に明確にする必要があるのは、GIL は Python

の機能ではなく、Python パーサー (CPython) を実装するときに導入された概念であるということです。 )。

C は一連の言語 (文法) 標準ですが、さまざまなコンパイラを使用して実行可能コードにコンパイルできます。 GCC、INTEL C、Visual C などの有名なコンパイラ

同様のことが Python にも当てはまり、CPython、PyPy、Psyco などの異なる Python 実行環境を通じて同じコードを実行できます。

他の Python インタープリターには GIL

がない可能性があります。たとえば、Jython (JVM) と IronPython (CLR) には GIL がありませんが、CPython と PyPy には GIL があります。

これは、CPython がほとんどの環境でデフォルトの Python 実行環境であるためです。したがって、多くの人の概念では、CPython は Python であり、GIL は Python 言語の欠陥であると当然のことと考えています。ここで明確にしておきます: GIL は Python の機能ではありません。Python は GIL にまったく依存する必要はありません

#GIL の本質はミューテックス ロックです

GIL の本質は、ミューテックス ロックはミューテックス ロックであるため、すべてのミューテックス ロックの本質は同じであり、同時操作を直列操作に変換することで、共有データを同時に 1 つのタスクによってのみ変更できるように制御します。これにより、データのセキュリティが確保されます。

確かなことは、さまざまなデータのセキュリティを保護するには、さまざまなロックを追加する必要があるということです。

GIL の仕組み: たとえば、下の図は、Python プログラムで GIL がどのように動作するかを示した例です。このうち、スレッド 1、2、3 が順番に実行され、各スレッドが実行を開始すると、他のスレッドが実行されないように GIL をロックし、同様に、各スレッドが一定期間実行を終了すると、GIL を解放します。他のスレッドの実行を許可する スレッドはリソースの利用を開始します。

コンピューティング集約型

コンピューティング集約型タスクは、大量の計算が必要であり、CPU リソースを消費するという特徴があります。

まず、計算を多用する単純な例を見てみましょう:

'''
@Author: Runsen
@微信公众号: Python之王
@博客: https://blog.csdn.net/weixin_44510615
@Date: 2020/6/4
'''import time
COUNT = 50_000_000def count_down():
   global COUNT   while COUNT > 0:
       COUNT -= 1s = time.perf_counter()
count_down()
c = time.perf_counter() - s
print('time taken in seconds - >:', c)

time taken in seconds - >: 9.2957003复制代码

これは 1 つのスレッドで、時間は 9 秒です。2 つのスレッドを使用して結果を見てみましょう:

'''
@Author: Runsen
@微信公众号: Python之王
@博客: https://blog.csdn.net/weixin_44510615
@Date: 2020/6/4
'''import timefrom threading import Thread

COUNT = 50_000_000def count_down():
   global COUNT   while COUNT > 0:
       COUNT -= 1s = time.perf_counter()
t1 = Thread(target=count_down)
t2 = Thread(target=count_down)
t1.start()
t2.start()
t1.join()
t2.join()
c = time.perf_counter() - s
print('time taken in seconds - >:', c)

time taken in seconds - >: 17.110625复制代码

プログラムの主な動作は計算です。CPU は待機しません。マルチスレッドに変更した後、スレッドを追加した後、スレッド間の頻繁な切り替えにより時間のオーバーヘッドが増加します。当然、時間は増加します。

IO 集中型の別のタイプがあります。ネットワークおよびディスク IO を伴うタスクはすべて IO 集中型タスクです。このタイプのタスクの特徴は、CPU 消費量が非常に少なく、タスクのほとんどが実行されることです。 IO の待機時間が経過し、操作が完了します (IO の速度が CPU やメモリの速度よりもはるかに遅いため)。 IO 集中型のタスクの場合、タスクが多いほど CPU 効率は高くなりますが、制限があります。最も一般的なタスクは、Web アプリケーションなどの IO 集中型のタスクです。

要約: io 集中型の作業 (Python クローラー) の場合、マルチスレッドによってコードの効率が大幅に向上します。 CPU を大量に使用するコンピューティング (Python データ分析、機械学習、深層学習) の場合、マルチスレッドはシングル スレッドよりも若干効率が劣る可能性があります。したがって、データ分野の効率を向上させるマルチスレッドなどは存在せず、演算能力を向上させる唯一の方法は、CPU を GPU と TPU にアップグレードすることです。

関連する無料学習の推奨事項: Python ビデオ チュートリアル

以上がマルチスレッドがシングルスレッドよりも高速であるというのは本当ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。