2009-07-22 7 views
2

Je fais de la programmation C++ liée au logiciel de cartographie et à la modélisation mathématique. Certains programmes prennent entre une heure et cinq heures pour effectuer et produire un résultat; Cependant, ils ne consomment que 50% de mon duo de base. J'ai essayé le code sur une autre machine à double processeur avec le même résultat.Forcer le programme/thread à utiliser 100% des ressources du (des) processeur (s)

Existe-t-il un moyen de forcer un programme à utiliser toutes les ressources de processeur disponibles et la mémoire?

Note: J'utilise ubuntu et g ++

Répondre

10

Un fil ne peut fonctionner que sur un noyau à la fois. Si vous voulez utiliser les deux cœurs, vous devez trouver un moyen de faire la moitié du travail dans un autre thread.

Si cela est possible, et si oui comment diviser le travail entre les threads, dépend complètement du travail que vous faites.

Pour créer un nouveau fil, consultez le Boost.Thread docs ou le pthreads docs ou le Win32 API docs. [Modifier: d'autres personnes ont suggéré d'utiliser des bibliothèques pour gérer les threads pour vous. La raison pour laquelle je n'ai pas mentionné cela est que je n'en ai aucune expérience, pas parce que je ne pense pas que ce soit une bonne idée. Ils le sont probablement, mais tout dépend de votre algorithme et de votre plateforme. Les threads sont presque universels, mais attention, la programmation multithread est souvent difficile: vous créez beaucoup de problèmes pour vous-même.]

+0

@Edit: Oui, je ne vois pas l'intérêt d'utiliser des bibliothèques en C++ (comme boost). =/@ Mild-Offtopic: Oui, juste appris des threads, à peu près, en C++ récemment. :-) Bon conseil. :) – Zack

+1

@Zack: voulez-vous dire que vous ne voyez pas l'intérêt d'utiliser des bibliothèques en C++ en général? Parce que Boost est incroyable. – rlbond

+0

L'utilisation de bibliothèques/structures de données/modèles de conception simultanées simplifie certains des problèmes liés à la concurrence. Avec une conception adaptée, il suffira que quelques composants soient conscients de la concurrence et que le reste puisse être mono-thread, tout en profitant de tous les cœurs de processeurs disponibles. –

2

Pour utiliser pleinement un processeur multicœur, vous devez exécuter le programme multithread.

0

De 50%, voulez-vous dire un seul noyau?

Si l'application n'est pas multiprocessus ou multithread, elle ne peut en aucun cas utiliser les deux cœurs en même temps.

4

Vous devez avoir autant de threads en cours d'exécution que de cœurs de processeurs disponibles afin de pouvoir potentiellement utiliser toute la durée du processeur. (Vous pouvez toujours être préempté par d'autres tâches, cependant.)

Il existe plusieurs façons de le faire, et cela dépend entièrement de ce que vous traitez. Vous pouvez utiliser OpenMP ou une bibliothèque comme TBB pour le faire presque de manière transparente, cependant.

5

La méthode la plus rapide serait de lire à propos de openMP et de l'utiliser pour paralléliser votre programme.

Compile avec la commande g++ -fopenmp à condition que votre g ++ version est >=4

+0

Voulez-vous dire "version> = 4"? – dmckee

+0

J'ai fait merci, a changé –

3

Vous avez raison que vous aurez besoin d'utiliser une approche filetée pour utiliser plus d'un noyau. Boost possède une bibliothèque de threads, mais ce n'est pas tout le problème: vous devez également modifier votre algorithme pour qu'il fonctionne dans un environnement threadé.

Certains algorithmes ne peuvent tout simplement pas fonctionner en parallèle - par exemple, SHA-1 effectue un certain nombre de "passes" sur ses données, mais ils ne peuvent pas être enfilés car chaque passe dépend de la sortie avant . Afin de paralléliser votre programme, vous devez vous assurer que votre algorithme peut "diviser et vaincre" le problème en morceaux indépendants, qu'il peut ensuite traiter en parallèle avant de les combiner en un résultat complet.Quoi que vous fassiez, soyez très prudent pour vérifier l'exactitude de votre réponse. Enregistrez le code à un seul thread, de sorte que vous puissiez comparer sa sortie à celle de votre code multithread; threading est notoirement difficile à faire, et plein d'erreurs potentielles. Il vaut peut-être mieux que vous évitiez de filer entièrement, et essayez plutôt de profiler votre code: vous pouvez obtenir des améliorations de vitesse spectaculaires en optimisant le code le plus fréquemment exécuté, sans pour autant approcher les défis du threading.

+0

+1 pour l'importance de diviser votre ensemble de problèmes. – Alex

1

Une alternative au multi-thread est d'utiliser plus d'un processus. Vous devrez toujours diviser & votre problème en plusieurs morceaux indépendants.

+1

+1 Pourquoi les gens oublient-ils toujours cette option? Dans certains cas, il peut être plus facile d'obtenir une mise à l'échelle et une mise à l'échelle meilleures que les threads (pas de verrouillage pour accéder au même segment malloc/free dans le même espace d'adressage). –

0

Ajouter un while(1) { } quelque part dans main()? Ou pour faire écho à de vrais conseils, lancez plusieurs processus ou réécrivez le code pour utiliser des threads. Je recommande d'exécuter plusieurs processus, car cela est plus facile, bien que si vous devez accélérer une seule exécution, cela n'aide pas vraiment.

0

Pour arriver à 100% pour chaque thread, vous devez:

(dans chaque thread):

  • Éliminez tout le stockage secondaire I/O (lecture disque/écriture)
  • Éliminer toutes les E/S affichage (écran écrit/impression)
  • tous les mécanismes de verrouillage Éliminez (mutexs, sémaphores)
  • Éliminer toutes les E/S de stockage primaire (fonctionner strictement à partir des registres et du cache, pas DRAM).

Bonne chance pour votre réécriture!

+0

Parfois, il ne paie pas pour dire la vérité. – kmarsh

Questions connexes