2016-09-16 1 views
0

I ont besoin d'une itération d'une boucle parallèle pour utiliser 7 noyaux (ou rester à l'écart de 1 noyau), mais une autre itération à utiliser 8 (tous les noyaux) et essayé ci-dessous code:des affinités différentes de fil dans Parallel.For Itérations

Parallel.For(0,2,i=>{ 
    if(i=0) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255); 

    if(i==1) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254); 
    Thread.Sleep(25);// to make sure both set their affinities 
    Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity); 
}); 

cette sortie 255 pour les deux itérations. Ainsi, soit la boucle parallel.for utilise un thread unique pour eux, soit un paramètre définit également d'autres affinités d'itérations. Un autre problème est que ceci provient d'une application sensible à la latence et que tous ces paramètres d'affinité ajoutent une latence de 1 à 15 millisecondes.

Dois-je utiliser explicitement des discussions et ne devrais-je définir les affinités qu'une seule fois?

Modifier: J'ai essayé la version filetée, la même chose se produit. Même avec deux threads explicites, les deux écrit 255 à la console. Maintenant, il semble que cette commande est pour un processus pas un fil.

Le contexte OpenCL utilise des cœurs max pour l'exécution du noyau sur cpu en une seule itération. Autres itérations utilisant 1-2 cœurs pour copier les tampons et envoyer la commande aux périphériques. Lorsque cpu est utilisé par opencl, il utilise tous les cœurs et les périphériques n'ont pas assez de temps pour copier les buffers. La fission du dispositif semble être plus difficile que la résolution de ce problème.

+0

Je ne sais pas assez pour aider ici, mais est-ce que Parallel.For utilise des threads ou le pool de tâches? Parce que je l'ai vu créer et détruire des degrés de parallélisme basés sur la demande du pool de tâches. Je suis à peu près certain que les threads ne font pas ça. J'ai maxDegree fixé à 26 comparaisons de 3.2Billion d'exploitation, et les discussions actives fluctueraient entre aussi peu que 5 et 26 sur les six jours qu'il a fallu pour terminer. Donc, même si je ne peux pas aider, je suis vraiment intéressé par votre question. –

+0

Je ne pouvais pas trouver quelque chose comme minParallelismDegree pour cela, mais j'essaie des threads purs en utilisant le délégué de fonction anonyme et le gestionnaire d'événements maintenant. –

+0

C'est une option que vous définissez dans Parallel.For - https://msdn.microsoft.com/fr-fr/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism(v=vs.110).aspx comme je l'ai dit Je suis ignorant, mais cela pourrait vous aider à comprendre les choses sous le capot. –

Répondre

2

affinités différentes de fil dans Parallel.For Iterations

La question est trompeuse, car elle est basée sur l'hypothèse que Parallel API signifie plusieurs threads. Parallel API fait référence au traitement Data Parallel, mais ne fournit aucune garantie pour l'appel multiple threads, en particulier pour le code fourni ci-dessus, où il n'y a pratiquement aucun travail par thread.

Pour l'API Parallel, vous pouvez définir le degré maximum de Parallélisme, comme suit:

ParallelOptions parallelOption = new ParallelOptions(); 

parallelOption.MaxDegreeOfParallelism = Environment.ProcessorCount; 

Parallel.For(0, 20, parallelOption, i => 

Mais cela ne garantit le nombre de threads qui invocables à traitement parallèle, depuis Threads sont utilisés à partir de la ThreadPool et CLR décide à l'exécution, en fonction de la quantité de travail à traiter, si plus de one thread est requis pour le traitement.

Dans la même Parallel boucle pouvez-vous essayer ce qui suit, imprimer Thread.Current.ManageThreadId, cela donnerait une idée claire, en ce qui concerne le nombre de threads invoqués dans la boucle Parallel.

Dois-je utiliser explicitement des filets et ne devrais-je définir les affinités qu'une seule fois?

Modifier: J'ai essayé la version filetée, la même chose se produit. Même avec deux threads explicites, les deux écrit 255 à la console. Maintenant, il semble que cette commande est pour un processus pas un fil.

Pouvez-vous poster le code, pour plusieurs threads, pouvez-vous essayer quelque chose comme ça.

Thread[] threadArray = new Thread[2]; 
threadArray[0] = new Thread(<ThreadDelegate>); 
threadArray[1] = new Thread(<ThreadDelegate>); 
threadArray[0]. ProcessorAffinity = <Set Processor Affinity> 
threadArray[1]. ProcessorAffinity = <Set Processor Affinity> 

En supposant que vous attribuez l'affinité correctement, vous pouvez les imprimer et de trouver des valeurs différentes, vérifiez la ProcessThread.ProcessorAffinity suivante.Sur une autre note que vous pouvez voir dans le lien ci-dessus, vous pouvez définir la valeur hexadecimal en fonction de l'affinité du processeur, je ne sais pas ce que les valeurs 254, 255 indiquent, avez-vous vraiment serveur avec autant de processeurs.

EDIT:

Essayez l'édition suivante à votre programme, (basé sur le fait que deux ids de discussion sont s'imprimés), maintenant au moment où les deux fils un peu dans l'image, ils ont tous deux obtenir même valeur de variable i, ils ont besoin d'un local variable pour éviter la fermeture de problème

Parallel.For(0,2,i=>{ 
    int local = i; 
    if(local=0) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255); 

    if(local==1) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254); 
    Thread.Sleep(25);// to make sure both set their affinities 
    Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity); 
}); 

EDIT 2: (la plupart du temps Would fonctionne pas comme les deux threads peuvent augmenter, avant l'exécution de la logique réelle)

int local = -1; 
    Parallel.For(0,2,i=>{ 
    Interlocked.Increment(ref local); 
    if(local=0) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(255); 

    if(local==1) 
    Process.GetCurrentProcess().ProcessorAffinity = (System.IntPtr)(254); 
    Thread.Sleep(25);// to make sure both set their affinities 
    Console.WriteLine(Process.GetCurrentProcess().ProcessorAffinity); 
}); 
+0

Pour la première partie, il faut entre 20 et 200 millisecondes par itération, c'est-à-dire un équilibreur de charge et les balances fonctionnent sur tous les périphériques et leur donnent la même latence. –

+0

--------------- Thread.Current.ManageThreadId 10 Thread.Current.ManageThreadId 16 --------------- c'est comme ça mais seulement le deuxième change –

+0

Vérifiez l'édition, si cela se produit alors la plupart du temps c'est un problème de fermeture, car au moment où les deux fils viennent dans l'image, la valeur de i est 0 pour les deux –