Pertanyaan Menggunakan 100% dari semua inti dengan modul multiprocessing


Saya memiliki dua buah kode yang saya gunakan untuk belajar tentang multiprocessing di Python 3.1. Tujuan saya adalah menggunakan 100% dari semua prosesor yang tersedia. Namun, cuplikan kode di sini hanya mencapai 30% - 50% pada semua prosesor.

Apakah ada cara untuk 'memaksa' python menggunakan semua 100%? Apakah OS (windows 7, 64bit) membatasi akses Python ke prosesor? Sementara potongan kode di bawah ini berjalan, saya membuka task manager dan melihat lonjakan prosesor, tetapi tidak pernah mencapai dan mempertahankan 100%. Selain itu, saya dapat melihat beberapa proses python.exe dibuat dan dihancurkan sepanjang jalan. Bagaimana proses ini berhubungan dengan prosesor? Sebagai contoh, jika saya menelurkan 4 proses, setiap proses tidak menggunakan inti itu sendiri. Sebaliknya, apa proses yang digunakan? Apakah mereka berbagi semua inti? Dan jika demikian, apakah itu OS yang memaksa proses untuk berbagi inti?

cuplikan kode 1

import multiprocessing

def worker():
    #worker function
    print ('Worker')
    x = 0
    while x < 1000:
        print(x)
        x += 1
    return

if __name__ == '__main__':
    jobs = []
    for i in range(50):
        p = multiprocessing.Process(target=worker)
        jobs.append(p)
        p.start()

cuplikan kode 2

from multiprocessing import Process, Lock

def f(l, i):
    l.acquire()
    print('worker ', i)
    x = 0
    while x < 1000:
        print(x)
        x += 1
    l.release()

if __name__ == '__main__': 
    lock = Lock()
    for num in range(50):
        Process(target=f, args=(lock, num)).start()

32
2018-04-25 23:30


asal


Jawaban:


Untuk menggunakan 100% dari semua inti, jangan membuat dan menghancurkan proses baru.

Buat beberapa proses per core dan hubungkan dengan pipeline.

Pada level-OS, semua proses pipelined berjalan secara bersamaan.

Semakin sedikit Anda menulis (dan semakin banyak Anda delegasikan ke OS) semakin besar kemungkinan Anda untuk menggunakan sebanyak mungkin sumber daya.

python p1.py | python p2.py | python p3.py | python p4.py ...

Akan memaksimalkan penggunaan CPU Anda.


31
2018-04-25 23:33



Kamu dapat memakai psutil untuk pin setiap proses melahirkan multiprocessing ke CPU tertentu:

import multiprocessing as mp
import psutil


def spawn():
    procs = list()
    n_cpus = psutil.cpu_count()
    for cpu in range(n_cpus):
        affinity = [cpu]
        d = dict(affinity=affinity)
        p = mp.Process(target=run_child, kwargs=d)
        p.start()
        procs.append(p)
    for p in procs:
        p.join()
        print('joined')

def run_child(affinity):
    proc = psutil.Process()  # get self pid
    print('PID: {pid}'.format(pid=proc.pid))
    aff = proc.cpu_affinity()
    print('Affinity before: {aff}'.format(aff=aff))
    proc.cpu_affinity(affinity)
    aff = proc.cpu_affinity()
    print('Affinity after: {aff}'.format(aff=aff))


if __name__ == '__main__':
    spawn()

Catatan: Seperti dikomentari, psutil.Process.cpu_affinity tidak tersedia di macOS.


9
2018-02-12 20:23



Mengenai cuplikan kode 1: Berapa banyak inti / prosesor yang Anda miliki di mesin uji Anda? Tidak ada gunanya bagi Anda menjalankan 50 dari proses ini jika Anda hanya memiliki 2 inti CPU. Bahkan Anda memaksa OS untuk menghabiskan lebih banyak waktu beralih konteks untuk memindahkan proses dan mematikan CPU daripada melakukan pekerjaan yang sebenarnya.

Coba kurangi jumlah proses yang menghasilkan ke jumlah inti. Jadi "untuk saya dalam rentang (50):" seharusnya menjadi sesuatu seperti:

import os;
# assuming you're on windows:
for i in range(int(os.environ["NUMBER_OF_PROCESSORS"])):
    ...

Mengenai cuplikan kode 2: Anda menggunakan multiprocessing.Lock yang hanya dapat dipegang oleh satu proses pada satu waktu sehingga Anda benar-benar membatasi semua paralelisme dalam versi program ini. Anda telah membuat serial hal-hal sehingga proses 1 hingga 50 mulai, proses acak (katakanlah proses 7) memperoleh kunci. Proses 1-6, dan 8-50 semuanya berada di garis:

l.acquire()

Sementara mereka duduk di sana mereka hanya menunggu kunci yang akan dirilis. Tergantung pada penerapan Kunci primitif mereka mungkin tidak menggunakan CPU, mereka hanya duduk di sana menggunakan sumber daya sistem seperti RAM tetapi tidak melakukan pekerjaan yang bermanfaat dengan CPU. Proses 7 menghitung dan mencetak hingga 1000 dan kemudian lepaskan kunci. OS kemudian bebas menjadwalkan secara acak salah satu dari 49 proses yang tersisa untuk dijalankan. Yang mana pertama kali bangun pertama akan mendapatkan kunci berikutnya dan menjalankan sementara 48 sisanya menunggu di Kunci. Ini akan berlanjut untuk seluruh program.

Pada dasarnya, cuplikan kode 2 adalah contoh dari apa yang membuat konkurensi sulit. Anda harus mengelola akses dengan banyak proses atau utas ke beberapa sumber bersama. Dalam kasus khusus ini tidak ada alasan bahwa proses ini harus menunggu satu sama lain.

Jadi dari keduanya, Cuplikan 1 lebih dekat untuk lebih efisien dalam menggunakan CPU. Saya pikir benar menyetel jumlah proses untuk mencocokkan jumlah core akan menghasilkan hasil yang jauh lebih baik.


6
2018-04-26 04:05



Untuk menjawab pertanyaan Anda:

Apakah ada cara untuk 'memaksa' python menggunakan semua 100%?

Bukan yang saya dengar

Apakah OS (windows 7, 64bit) membatasi akses Python ke prosesor?

Ya dan Tidak, Ya: jika python mengambil 100%, windows akan membeku. Tidak, Anda dapat memberikan Admin Priviledges python yang akan mengakibatkan penguncian.

Bagaimana proses ini berhubungan dengan prosesor?

Mereka tidak, secara teknis pada tingkat OS mereka "proses" python adalah benang yang diproses oleh OS Handler karena perlu penanganan.

Sebaliknya, apa proses yang digunakan? Apakah mereka berbagi semua inti? Dan jika demikian, apakah itu OS yang memaksa proses untuk berbagi inti?

Mereka berbagi semua inti, kecuali Anda memulai contoh python tunggal yang memiliki afinitas yang diatur ke inti tertentu (dalam sistem multicore) proses Anda akan dipisah menjadi pemrosesan mana pun yang bebas-inti. Jadi ya, OS memaksa pembagian inti secara default (atau python secara teknis)

jika Anda tertarik dengan afinitas inti python, periksa paket afinitas untuk python.


-8
2018-04-25 23:43