Vitajte na [www.pocitac.win] Pripojiť k domovskej stránke Obľúbené stránky

Domáce Hardware Siete Programovanie Softvér Otázka Systémy

Ako môžem paralelizovať A pre slučku v Pythone zlepšený výkon?

Paralelizácia „pre„ slučku v Pythone pre zlepšený výkon spočíva v distribúcii iterácií slučky vo viacerých procesorových jadrách. Existuje niekoľko prístupov, z ktorých každý má svoje silné a slabé stránky:

1. Použitie „multiprocessing“: Toto je všeobecne najlepší prístup pre úlohy viazané na CPU (úlohy, ktoré trávia väčšinu času výpočtami). Vytvára viac procesov, z ktorých každý prevádzkuje časť slučky.

`` `Python

importovať multiprientovanie

def process_item (položka):

"" "Funkcia, ktorá sa má použiť na každú položku v slučke." "

# Váš kód na spracovanie jednej položky ide sem

Výsledok =položka * 2 # Príklad:Zdvojnásobte položku

výsledok návratnosti

Ak __name__ =='__main__':# Dôležité pre kompatibilitu so systémom Windows

položky =zoznam (rozsah (1000)) # Príklad Zoznam položiek

s multiprocessing.pool (processes =multiprocessing.cpU_count ()) ako fondy:

Výsledky =Pool.map (Process_item, položky)

Tlač (výsledky)

`` `

* `multiprocessing.pool`: Vytvára skupinu pracovných procesov. `multiprocessing.cpu_count ()` určuje optimálny počet procesov založených na jadrách vášho systému. V prípade potreby môžete toto číslo upraviť.

* `Pool.map`: Aplikuje funkciu `process_item` na každú položku v položke„ ITarable. Zaoberá sa efektívnym distribúciou práce a zhromažďovaním výsledkov.

* `if __name__ =='__main __':`: Je to rozhodujúce, najmä v systéme Windows, aby sa zabránilo rekurzívnemu vytváraniu viacerých procesov.

2. Pomocou `concurrent.futures`: Poskytuje rozhranie na vyššej úrovni na viacnásobné spracovanie a závity, ktoré ponúka väčšiu flexibilitu.

`` `Python

import súbežné.

def process_item (položka):

"" "Funkcia, ktorá sa má použiť na každú položku v slučke." "

# Váš kód na spracovanie jednej položky ide sem

Výsledok =položka * 2 # Príklad:Zdvojnásobte položku

výsledok návratnosti

Ak __name__ =='__main__':

položky =zoznam (rozsah (1000))

s Concurrent.futures.ProcesspooLExecutor () ako exekútor:

výsledky =zoznam (executor.map (proces_item, položky))

Tlač (výsledky)

`` `

Je to veľmi podobné „multiprientovaniu“, ale často sa považuje za viac pythonické a ľahšie použiteľné. `ProcessPooLExecutor` používa procesy, zatiaľ čo` ThreadPooLExecutor` používa vlákna (lepšie pre úlohy viazaných na I/O).

3. Pomocou `Threading` (pre úlohy viazaných na I/O): Ak vaša slučka zahŕňa veľa čakania (napr. Žiadosti o sieť, I/O súboru), vlákna môžu byť efektívnejšie ako procesy. Globálny zámok tlmočníka (GIL) v Cpython však obmedzuje skutočný paralelizmus pre úlohy viazaných na CPU v vláknach.

`` `Python

importovaný závit

def process_item (položka, výsledky):

"" "Funkcia, ktorá sa má použiť na každú položku v slučke." "

# Váš kód na spracovanie jednej položky ide sem

Výsledok =položka * 2 # Príklad:Zdvojnásobte položku

resuls.ppend (výsledok)

Ak __name__ =='__main__':

položky =zoznam (rozsah (1000))

Výsledky =[]

vlákna =[]

pre položky v položkách:

vlákno =závitové

vlákna.prend (vlákno)

vlákno.start ()

Pre vlákno v vláknach:

vlákno.join ()

Tlač (výsledky)

`` `

Tento príklad je zložitejší, pretože musíte výslovne spravovať vlákna a zoznam zdieľaných výsledkov. `Concurrent.futures.Threadpooxecutor` to významne zjednodušuje.

Výber správnej metódy:

* CPU viazané: Použite „multiprocessing“ alebo `concurrent.futures.ProcesspooLexecutor`. Procesy obchádzajú GIL a umožňujú skutočný paralelizmus.

* i/o-viazané: Použite `concurrent.futures.ThreadpooLExecutor`. Vlákna sú ľahšie ako procesy a režijné náklady na prepínanie kontextu je nižšie. Ak je I/O veľmi pomalý, môže to zlepšiť výkon aj pri GIL.

* zmiešané: Ak má vaša slučka časti viazaných na procesor a I/O viazané na I/O, možno budete potrebovať sofistikovanejší prístup, potenciálne kombinovať vlákna a procesy alebo pomocou asynchrónneho programovania (napr. „Asyncio`).

Dôležité úvahy:

* Riadenie: Vytváranie a správa procesov alebo vlákien predstavuje režijné náklady. Paralelizácia poskytuje výhodu iba vtedy, ak je práca vykonaná na položku dostatočne podstatná na to, aby prevážila túto režijnú nákladu.

* Zdieľanie údajov: Zdieľanie údajov medzi procesmi je zložitejšie ako zdieľanie údajov medzi vláknami. V prípade potreby zvážte použitie frontov alebo iných komunikačných mechanizmov medzier.

* ladenie: Ladenie paralelného kódu môže byť náročné. Začnite s malými príkladmi a postupne zvyšujte zložitosť.

Nezabudnite profilovať svoj kód na meranie zlepšenia výkonu po paralelizácii. Je možné, že paralelizácia neposkytuje významný prínos, alebo dokonca spomaľuje veci, ak je režijné náklady príliš vysoké alebo úloha nie je vhodná na paralelizáciu.

Najnovšie články

Copyright © počítačové znalosti Všetky práva vyhradené