2017-05-04 4 views
0

Gibt es eine Möglichkeit, den folgenden Code parallelisiert werden? Ich schaute in Cytons Prange, konnte aber nicht herausfinden, wie es funktioniert. Vereinheitlicht der Prange die internen Schleifen auf verschiedenen Kernen? Für den Code unten, wie kann ich es parallelisieren?Parallelisierung mit Cython

@cython.boundscheck(False) 
def gs_iterate_once(double[:,:] doc_topic, 
        double[:,:] topic_word, 
        double[:] topic_distribution, 
        double[:] topic_probabilities, 
        unsigned int[:,:] doc_word_topic, 
        int num_topics): 
    cdef unsigned int doc_id 
    cdef unsigned int word_id 
    cdef unsigned int topic_id 
    cdef unsigned int new_topic 
    for i in xrange(doc_word_topic.shape[0]): 
    doc_id = doc_word_topic[i, 0] 
    word_id = doc_word_topic[i, 1] 
    topic_id = doc_word_topic[i, 2] 

    doc_topic[doc_id, topic_id] -= 1 
    topic_word[topic_id, word_id] -= 1 
    topic_distribution[topic_id] -= 1 

    for j in xrange(num_topics): 
     topic_probabilities[j] = (doc_topic[doc_id, j] * topic_word[j, word_id])/topic_distribution[j] 

    new_topic = draw_topic(np.asarray(topic_probabilities)) 

    doc_topic[doc_id, new_topic] += 1 
    topic_word[new_topic, word_id] += 1 
    topic_distribution[new_topic] += 1 
    # Set the new topic 
    doc_word_topic[i, 2] = new_topic 

Antwort

2

prange verwendet OpenMP, die in der Tat shared-memory parallelism ist. Auf einem einzelnen Computer werden also Threads erstellt, die auf den verschiedenen verfügbaren Kernen laufen und Zugriff auf denselben Speicherpool haben.

Für die Routine, die Sie zeigen, ist der erste Schritt zu verstehen, welcher Teil parallelisiert werden kann. Wenn Daten als erster Index i verwendet werden, ist das Problem typischerweise parallelisierbar, wenn nur das Element i und nicht etwa i-1 oder i+1 betrieben wird. Dies ist hier nicht der Fall, also müssen Sie einen Weg finden, die Berechnung unabhängiger zu machen.

Eigentlich das spezifische Muster parallel über eine SO beantworten ist zu finden, aber ich werde ein paar Tipps zu geben:

  1. Was ist innen die Prange alle cythonized werden müssen. Python-Aufrufe sind in einem Thread nicht möglich. + Vorschlag von @DavidW: Python-Aufrufe sind möglich, wenn Teil eines with gil Blocks ist.
  2. Ein typischer Rat hier ist zu überprüfen, sobald Ihr Code unabhängig von der Schleife Bestellung gemacht wurde, ob Ihre Ergebnisse die gleichen sind, wenn Sie den Index von n-1 bis 0 statt von 0 bis n-1
  3. ein paar kommentierte und anschauliche Beispiele: https://homes.cs.washington.edu/~jmschr/lectures/Parallel_Processing_in_Python.htmlCython prange slower for 4 threads then with rangehttp://nealhughes.net/parallelcomp2/http://www.perrygeo.com/parallelizing-numpy-array-loops-with-cython-and-mpi.html
+0

Re Punkt 1 - Kann ich einen Zusatz vorschlagen: Python-Aufrufe sind erlaubt, wenn Sie sie in einen 'mit gil:' Block setzen. Vorausgesetzt, dass dies ein kleiner Teil der Schleife ist, sind die Leistungskosten nicht so schlecht. – DavidW

2

@ PierredeBuyl Antwort gibt eine gute übersicht darüber, was prange tut und wie es zu benutzen.

Dies ist mehr ein paar spezifischen Kommentare zu Ihrem Kodexes:

  • Sie können nicht die äußeree Schleife parallelisieren:

    doc_topic[doc_id, topic_id] -= 1 
    

    und die ähnlichen für andere Variablen und für +=1. Diese ändern eine Variable, die von allen Schleifen gemeinsam genutzt wird und inkonsistente Ergebnisse verursachen wird.

  • Ein ähnliches Problem existiert mit topic_probabilities[j] = ..., wenn Sie die äußere Schleife parallelisieren.

  • Sie könnten leicht die innere Schleife for j in xrange(num_topics): parallelisieren - das ändert nur Sachen, die auf den Index 'j' abhängt, so gibt es kein Problem mit den Threads kämpfen, um die gleichen Daten zu ändern. (Allerdings gibt es eine Performance Kosten jedes Mal, wenn Sie eine Multi-Thread-Region beginnen, so dass Sie in der Regel versuchen, die äußeree Schleife parallelisieren, anstatt dies zu vermeiden - in Abhängigkeit von der Größe der Arrays Sie nicht viel gewinnen können)