2

Je sais que cela aurait pu être demandé dans le passé, mais je suis un débutant absolu dans Julia.Code parallèle pour calculs multiples asynchrones dans Julia

J'ai un code simple dans Julia que je voudrais exécuter en parallèle.

#--Two Calculations during the Loop-- 

vt_0=0 
ct_0=0 

for i=1:10 

#--Calculation vt_1 
vt_1=max(rand(1:i),vt_0,ct_0) 


#--Calculation ct_1 
ct_1=min(rand(1:i),vt_0,ct_0) 

ct_0=ct_1 
vt_0=vt_1 

end 

Comme vous pouvez le voir, le calcul des vt_1 et ct_1 pourrait se faire en même temps (ou au cours de la même boucle sans avoir le calcul ct_1 en attente pour le calcul vt_1).

Quelqu'un peut-il m'aider à modifier ce code pour fonctionner en parallèle? Devrais-je télécharger un script/une bibliothèque de Julia? (J'ai un beaucoup plus grand et le code compliqué pour programmation dynamique, mais l'essence est la même.)

Nous vous remercions à l'avance

+1

Vous pouvez modifier le titre comme par paralléliser un peuple de boucle de base serait-vous deviner dire chaque itération de la boucle sur un noyau séparé alors que (je comprends) vous voulez vraiment juste exécuter plusieurs expressions de manière asynchrone et ensuite attendre toutes les réponses. –

+0

Terminé. J'espère que cela a plus de sens maintenant. – Gunnar

Répondre

3

Est-ce ce que vous cherchez? Probablement plus rapide de ne pas utiliser la fonction anonyme comme je l'ai ici mais à part ça.

addprocs(2)   
vt_0 = 0; ct_0 = 0; 
for i=1:10 
    #--Calculation vt_1 
    vt_1 = remotecall((x,y)->max(rand(1:i),x,y), 2, vt_0, ct_0) 

    #--Calculation ct_1 
    ct_1 = remotecall((x,y)->min(rand(1:i),x,y), 3, vt_0, ct_0) 

    ct_0 = fetch(ct_1) 
    vt_0 = fetch(vt_1) 
end 

ou sans funcs anonymes:

addprocs(2) 
@everywhere minrand(i,x,y) = min(rand(1:i),x,y) 
@everywhere maxrand(i,x,y) = max(rand(1:i),x,y) 
vt_0 = 0; ct_0 = 0; 

for i=1:10 
    #--Calculation vt_1 
    vt_1 = remotecall(maxrand, 2, i, vt_0, ct_0) 

    #--Calculation ct_1 
    ct_1 = remotecall(minrand, 3, i, vt_0, ct_0) 

    ct_0 = fetch(ct_1) 
    vt_0 = fetch(vt_1) 
end 
+0

Exactement ce que je cherchais! Merci beaucoup. – Gunnar

+0

Salut! J'ai essayé ces deux versions parallèles (avec des paramètres différents) et le temps qu'il faut pour calculer en parallèle est robuste beaucoup plus longtemps que séquentiellement. Par exemple, en changeant le nombre d'itérations de 10 à 10000, mon code séquentiel simple prend une moyenne de 0,010 secondes, alors que dans le code parallèle (le second que vous fournissez), il faut en moyenne 27 secondes pour terminer . Pensez-vous que je fais quelque chose de mal? Peut-être qu'il me manque quelque chose? J'utilise un ordinateur portable Jupyter juste au cas où. TIA! – Gunnar

+0

Donc 27 secondes semble trop grande pour qu'il y ait autre chose là-bas mais ... il y aura toujours un surcoût (lié à IO) pour envoyer des données vers/depuis un autre processeur qui dépasse dans ce cas le gain de la division du calcul . (Si vous aviez 20 expressions qui pourraient être divisées dans chaque boucle, l'histoire pourrait être différente). Vous * pourriez * avoir plus de chance en essayant multi-threading - sinon aller avec quel chronométrage vous dit est le plus rapide! –

2

Je serai curieux de savoir s'il y a une réelle bonne réponse à cette question. L'exécution normalement parallèle dans Julia fait partie de Base, donc vous n'avez besoin d'aucune bibliothèque spéciale pour cela. Mais votre cas d'utilisation n'est pas typique pour l'exécution parallèle IIUC. Normalement, un parallèle pour une boucle itérerait sur l'appel de la même expression avec des valeurs différentes - c'est-à-dire que vous exécuteriez l'expression associée à i = 1 sur un cœur, i = 2 sur un autre et fusionner les résultats. Il y a une bonne explication ici: https://docs.julialang.org/en/latest/manual/parallel-computing/#Parallel-Map-and-Loops-1

Ce que vous suggérez est d'exécuter différents morceaux du programme (expressions différentes) sur différents cœurs. EDIT: Il y a une bonne description de la façon de le faire dans la réponse d'Alexander.

+0

Ai-je raté quelque chose? Ou est-ce que ce que je mets a du sens? –

+0

AFAICS c'est tout à fait logique :-) Je vois qu'il pourrait y avoir des cas d'utilisation pour faire quelque chose comme ça. –