Multiproses dengan antrian bersama dan kriteria akhir

Saya memiliki fungsi asli yang ingin saya alihkan ke multiproses:

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

Jika valid = True setelah pengujian, ia akan menghitung parameter pengoptimalan yang disebut optim_param dan mencoba meminimalkannya. Jika berada di bawah ambang batas tertentu, optim_param < 0.3, saya keluar dari lingkaran dan mengambil nilai ini sebagai jawaban saya.

Masalah saya adalah saat saya mengembangkan model, kompleksitasnya mulai meningkat, dan komputasi single thread memakan waktu terlalu lama. Saya ingin memproses komputasi secara paralel. Karena setiap proses harus membandingkan hasil yang diperoleh dengan nilai s dengan nilai optimal saat ini, saya mencoba mengimplementasikan Antrian.

Ini pertama kalinya saya melakukan multiprosesor, dan meskipun saya merasa berada di jalur yang benar, saya merasa kode saya berantakan dan tidak lengkap. Bisakah saya mendapatkan bantuan?

Terimakasih


person Mathieu    schedule 22.02.2018    source sumber
comment
Selain membuat komputer saya mogok, solusi ini tidak banyak berpengaruh :/   -  person Mathieu    schedule 23.02.2018
comment
Anda menunjukkan contoh masukan padashift dan frequencies. Bisakah Anda menunjukkan contoh masukan t0 dan tf? Selain itu, bisakah Anda merevisi shift dengan langkah yang lebih sedikit? Katakanlah, 1000 atau 10000 berjalan secara paralel untuk memudahkan pengujian awal?   -  person thewaywewere    schedule 27.02.2018
comment
t0 dan tf adalah waktu awal dan akhir yang digunakan untuk menghitung garis waktu (yang merupakan daftar instan, katakanlah [0, 50, 100, 150] untuk sinyal 20 Hz). Katakanlah t0 = 0 dan tf = 200. Untuk shift tentu saja kita bisa mengambil np.arange(0, 2, 0.1) sebagai permulaan.   -  person Mathieu    schedule 27.02.2018


Jawaban (1)


Daripada membuat proses secara manual untuk setiap kasus, pertimbangkan untuk menggunakan Pool.imap_unordered. Triknya adalah bagaimana mematikan dengan bersih ketika hasil yang lumayan diperoleh: Anda dapat menerapkannya dengan meneruskan generator yang keluar lebih awal jika ada tanda yang disetel untuk memeriksa setiap siklus. Program utama membaca dari iterator, mempertahankan hasil terbaik yang terlihat, dan menyetel tanda jika sudah cukup baik. Trik terakhir adalah memperlambat pembacaan thread (internal) dari generator untuk mencegah tumpukan besar tugas terjadwal yang harus ditunggu (atau, secara tidak sengaja, dihentikan) setelah hasil yang baik diperoleh. Mengingat banyaknya proses dalam kumpulan, kecepatan tersebut dapat dicapai dengan semaphore.

Berikut ini contoh (dengan analisis sepele) untuk ditunjukkan:

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)

Tentu saja ada cara lain untuk membagikan semaphore dan flag interupsi dengan generator; cara ini menggunakan tipe data yang jelek tetapi memiliki kelebihan karena tidak menggunakan variabel global (atau bahkan penutupan).

person Davis Herring    schedule 26.02.2018
comment
Saya agak mengerti idenya. Saya akan memeriksanya, namun, ini adalah pertama kalinya saya menggunakan multiprosesor, dan meskipun saya bukan pemula dalam python, saya masih jauh dari fasih. - person Mathieu; 26.02.2018
comment
Saya mendapatkan ide di baliknya, tetapi saya tidak dapat menghasilkan kode yang berfungsi sendiri... Meskipun banyak percobaan dan pc crash x') - person Mathieu; 26.02.2018
comment
Terima kasih, saya akan memeriksanya besok. - person Mathieu; 27.02.2018