การประมวลผลหลายตัวด้วยคิวที่ใช้ร่วมกันและเกณฑ์การสิ้นสุด

ฉันมีฟังก์ชันดั้งเดิมที่ฉันต้องการเปลี่ยนไปใช้มัลติโพรเซส:

def optimal(t0, tf, frequences, delay, ratio = 0):

    First = True                            # First        
    for s in delay:
        delay = 0                           # delay between signals,
        timelines = list()

        for i in range(len(frequences)):
            timelines.append(time_builder(frequences[i], t0+delay, tf))
            delay += s

       trio_overlap = trio_combination(timelines, ratio)

        valid = True
        for items in trio_overlap.values():
            if len(list(set(items))) == len(items):
                continue
            else:
                valid = False

        if not valid:
            continue

        overlap = duo_combination(timelines)

    optimal = ... depending of conditions        
    return optimal

หาก valid = True หลังการทดสอบ ระบบจะคำนวณพารามิเตอร์การปรับให้เหมาะสมที่เรียกว่า optim_param และพยายามย่อให้เล็กสุด หากต่ำกว่าเกณฑ์ที่กำหนด optim_param < 0.3 ฉันจะแยกออกจากวงและรับค่านี้เป็นคำตอบ

ปัญหาของฉันคือในขณะที่ฉันพัฒนาแบบจำลอง ความซับซ้อนเริ่มเพิ่มขึ้น และการคำนวณแบบเธรดเดียวใช้เวลานานเกินไป ฉันต้องการประมวลผลการคำนวณแบบขนาน เนื่องจากแต่ละกระบวนการจะต้องเปรียบเทียบผลลัพธ์ที่ได้รับด้วยค่า s กับค่าที่เหมาะสมที่สุดในปัจจุบัน ฉันจึงพยายามใช้คิว

นี่เป็นครั้งแรกของฉันที่ทำการประมวลผลหลายตัว และแม้ว่าฉันคิดว่าฉันมาถูกทางแล้ว แต่ฉันรู้สึกว่าโค้ดของฉันยุ่งเหยิงและไม่สมบูรณ์ ฉันขอความช่วยเหลือได้ไหม?

ขอขอบคุณ: D


person Mathieu    schedule 22.02.2018    source แหล่งที่มา
comment
นอกจากจะทำให้คอมพิวเตอร์ของฉันพังแล้ว วิธีแก้ไขปัญหานี้ยังมีผลเพียงเล็กน้อย :/   -  person Mathieu    schedule 23.02.2018
comment
คุณแสดงอินพุตตัวอย่างบนshift และ frequencies คุณช่วยแสดงอินพุตตัวอย่างของ t0 และ tf ได้ไหม นอกจากนี้ คุณสามารถแก้ไข shift โดยใช้ขั้นตอนน้อยลงได้ไหม สมมติว่า 1000 หรือ 10000 ทำงานขนานกันเพื่อความสะดวกในการทดสอบเบื้องต้น   -  person thewaywewere    schedule 27.02.2018
comment
t0 และ tf คือเวลาเริ่มต้นและครั้งสุดท้ายที่ใช้ในการคำนวณไทม์ไลน์ (ซึ่งเป็นรายการของช่วงเวลาทันที สมมติว่า [0, 50, 100, 150] สำหรับสัญญาณ 20 Hz) สมมติว่า t0 = 0 และ tf = 200 สำหรับกะ แน่นอนว่าเราสามารถเริ่มต้นด้วย np.arange(0, 2, 0.1) ได้   -  person Mathieu    schedule 27.02.2018


คำตอบ (1)


แทนที่จะสร้างกระบวนการสำหรับแต่ละกรณีด้วยตนเอง ให้พิจารณาใช้ Pool.imap_unordered เคล็ดลับคือวิธีการปิดระบบอย่างหมดจดเมื่อได้รับผลลัพธ์ที่ผ่านได้: คุณสามารถดำเนินการนี้ได้โดยการส่งผ่านตัวสร้างที่ออกก่อนกำหนดในกรณีที่มีการตั้งค่าแฟล็กที่จะตรวจสอบทุกรอบ โปรแกรมหลักอ่านจากตัววนซ้ำ รักษาผลลัพธ์ที่ดีที่สุดที่เห็น และตั้งค่าสถานะเมื่อดีพอ เคล็ดลับสุดท้ายคือการชะลอการอ่านเธรด (ภายใน) จากตัวสร้าง เพื่อป้องกันงานค้างตามกำหนดเวลาจำนวนมากที่ต้องรอ (หรือถูกฆ่าอย่างไม่สะอาด) หลังจากได้รับผลลัพธ์ที่ดี เมื่อพิจารณาถึงจำนวนของกระบวนการในพูล การเว้นจังหวะนั้นสามารถทำได้โดยใช้เซมาฟอร์

นี่คือตัวอย่าง (พร้อมการวิเคราะห์เล็กน้อย) เพื่อสาธิต:

import multiprocessing,threading,os

def interrupted(data,sem,interrupt):
  for x in data:
    yield x
    sem.acquire()
    if interrupt: break

def analyze(x): return x**2

np=os.cpu_count()
pool=multiprocessing.Pool(np)
sem=threading.Semaphore(np-1)
token=[]                        # mutable

vals=pool.imap_unordered(analyze,interrupted(range(-10,10),sem,token))
pool.close()                    # optional: to let processes exit faster

best=None
for res in vals:
  if best is None or res<best:
    best=res
    if best<5: token.append(None) # make it truthy
  sem.release()
pool.join()

print(best)

แน่นอนว่ามีวิธีอื่นในการแบ่งปันสัญญาณและแฟล็กขัดจังหวะกับตัวสร้าง วิธีนี้ใช้ประเภทข้อมูลที่น่าเกลียด แต่มีข้อดีคือไม่มีตัวแปรร่วม (หรือแม้แต่การปิด)

person Davis Herring    schedule 26.02.2018
comment
ฉันก็เข้าใจนะ ฉันจะลองดู แต่นี่เป็นครั้งแรกที่ฉันใช้การประมวลผลหลายตัว และแม้ว่าฉันจะไม่ใช่มือใหม่ใน Python แต่ฉันก็ยังห่างไกลจากความคล่อง - person Mathieu; 26.02.2018
comment
ฉันได้รับแนวคิดเบื้องหลัง แต่ฉันไม่สามารถสร้างโค้ดที่ใช้งานได้ด้วยตัวเอง... แม้จะมีการทดลองหลายครั้งและพีซีขัดข้อง x') - person Mathieu; 26.02.2018
comment
ขอบคุณครับ พรุ่งนี้จะลองดูครับ - person Mathieu; 27.02.2018