IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

CppCon 2014 - La programmation multicœur dans les jeux C++
Une vidéo de Jeff Preshing

Le , par LittleWhite

0PARTAGES

4  0 
Jeff Preshing, architecte logiciel à Ubisoft Montréal nous montre les contraintes liés à la programmation multicoeurs dans les jeux vidéos AAA.
Dans cette vidéo, vous comprendrez mieux comment découper la boucle principale du jeu afin de paralléliser les calculs et comment utiliser les nouveautés du C++11 pour les opérations atomiques.

Bonne vidéo.

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de
https://www.developpez.com
Le 04/01/2015 à 20:45
"CPU manages its cores at very low level" = programmation multicoeurs = mulitthreading

https://software.intel.com/en-us/com...1#comment-form

Il y a une différence entre thread et coeurs du CPU:


* thread = file d'attente d'instruction asm de tous les programmes tournant sur l'OS, organisation ? pos = instruction du programme#1 , pos-1 = instruction du programme#2.
* coeurs = vitesse d'éxécution d'instruction * nbr_coeurs
1  0 
Avatar de Astraya
Membre chevronné https://www.developpez.com
Le 05/01/2015 à 16:09
"CPU manages its cores at very low level" = programmation multicoeurs = mulitthreading
https://software.intel.com/en-us/com...1#comment-form
Il y a une différence entre thread et coeurs du CPU:
Dans le cas du task scheduler c'est idem, tu creer autant de thread que de core, et certaines architecture (Playstation par exemple) permette de lancer ton thread sur un SPU unique.

Uh, cela me semble être une erreur. volatile ne fait qu'interdire au compilateur de faire le mariole avec les lecture/ecriture optimisées en registre, aucun mécanisme d'atomicité n'entre en jeu.
Et côté pédagogique, il faut par ailleurs justement marteler que les volatile n'ont rien à voir avec l'atomicité car c'est une croyance ancrée par VC++ qui n'était ainsi pas conforme au standard.
Pour le compilateur de Visual Studio (depuis 2003), le mot clé volatile empêche de re-ordering de la variable ==>http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Je pense qu'il ne parle vraiment que du compilateur Visual Studio ici, les autres comme GCC je ne sais pas trop, il doit exister des options de compilations pour faire de même...

On peut voir à partir de la 24min de la vidéo que le compilateur PowerPC fait un peu n'importe quoi, pourquoi changer l'ordre des instructions de manière aussi brutale ? On dirait plus un bug que de l'optimisation.
Non c'est tout a fait normal, il existe 2 type de re-ordering, celle faite par le compilateur et celle faite par le processeur. Seulement 1% des programmeurs s'en souci car le re-ordering devient dérangeant lors d'une application mutlithread, et le plus souvent, l'utilisation de semarphore et mutex cache le problème au yeux du programmeur, ce qui n'est pas du tout le cas en lock free

Pourquoi ne pas simplement utiliser un lock ?
Le lock comme le semaphore apporte de la contention et des appels au système qui coute énormément de temps, tu peux avoir un gain de 10% sur un système comme le task scheduler. Il existe une autre petite méthode mais à utiliser avec précaution, c'est le spinlock ( utilisation des atomics oblige )

pas optimal le code de l'exemple (try_pop/try_push): une semantics acquire/release va être suffisant et plus performant. là on a une semantics memory_order_seq_cst c'est tout à fait superflue
C'est du psedo code, le but ici est de faire comprendre le raisonnement lié au lockfree queue.

Il exite un très bon articile d'un autre lead de Ubisoft Montreal dans le livre Game Programming Gems 8 de Jean-François Dubé qui parle également du meme systeme. " Efficient and Scalable Mutli-Core Programming"
1  0 
Avatar de MoDDiB
Membre expert https://www.developpez.com
Le 23/12/2014 à 12:20
*Erreur 404*

Je répondais à ce post en fait : http://www.developpez.net/forums/d14...p-jeux-triple/
...
0  0 
Avatar de germinolegrand
Membre expert https://www.developpez.com
Le 04/01/2015 à 23:01
les opérations atomiques bas niveau (similaires aux variables volatiles du C/C++).
Uh, cela me semble être une erreur. volatile ne fait qu'interdire au compilateur de faire le mariole avec les lecture/ecriture optimisées en registre, aucun mécanisme d'atomicité n'entre en jeu.

Et côté pédagogique, il faut par ailleurs justement marteler que les volatile n'ont rien à voir avec l'atomicité car c'est une croyance ancrée par VC++ qui n'était ainsi pas conforme au standard.
0  0 
Avatar de guillaume07
Débutant https://www.developpez.com
Le 05/01/2015 à 13:27
pas optimal le code de l'exemple (try_pop/try_push): une semantics acquire/release va être suffisant et plus performant. là on a une semantics memory_order_seq_cst c'est tout à fait superflue

Pourquoi ne pas simplement utiliser un lock ?
car ça apporte de la contention
0  0 
Avatar de germinolegrand
Membre expert https://www.developpez.com
Le 05/01/2015 à 14:10
Citation Envoyé par guillaume07 Voir le message
pas optimal le code de l'exemple (try_pop/try_push): une semantics acquire/release va être suffisant et plus performant. là on a une semantics memory_order_seq_cst c'est tout à fait superflue
En effet. Mais c'est parce qu'il me semble qu'il précise que dans le vrai code c'est acquire/release (ce que je fais dans mon code aussi) et qu'il n'a pas souhaité compliquer l'exemple puisque le code est fonctionnel (l'optimisation se fait facilement lorsqu'on a étudié les barrières mémoire), ce qui est toujours le cas en C++11 lorsqu'on utilise les atomic.

@Gugelhupf: Un seul thread est autorisé à appeler tryPush, et un seul thread est autorisé à appeler tryPop.
0  0 
Avatar de Bousk
Rédacteur/Modérateur https://www.developpez.com
Le 05/01/2015 à 14:39
Je n'ai pas encore vu la vidéo, mais ce tryPush est une liste "thread-safe".
Son utilisation est justement pas pour 2 threads fassent un tryPush mais pour un unique thread en écriture, et un unique en lecture.
0  0 
Avatar de Astraya
Membre chevronné https://www.developpez.com
Le 05/01/2015 à 16:19
Intel a également fait de très bonne vidéo sur la création de task dans un game engine.

https://software.intel.com/en-us/vid...threads-part-1
https://software.intel.com/en-us/vid...threads-part-2
https://software.intel.com/en-us/vid...threads-part-3

Bon la troisième vidéo est plus branché sur leur techno TBB. Mais bon, c'est toujours bon a connaitre pour ceux que ça intéresse.
0  0 
Avatar de Gugelhupf
Modérateur https://www.developpez.com
Le 05/01/2015 à 13:25
On peut voir à partir de la 24min de la vidéo que le compilateur PowerPC fait un peu n'importe quoi, pourquoi changer l'ordre des instructions de manière aussi brutale ? On dirait plus un bug que de l'optimisation.

Aussi il y a un truc que je ne comprends pas :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
T m_items[size]; 
atomic<int> m_writePos; 
// ... 
 
bool tryPush(const T& item) 
 { 
    int w = m_writePos 
    if (w >= size) 
        return false; 
    m_items[w] = item; 
    m_writePos = w + 1; 
    return true; 
}
Pourquoi ne pas simplement utiliser un lock ? Prenons l'exemple où 2 threads exécutent en même temps la méthode tryPush :
PS: On va commencer avec m_writePos = 0.

Ligne du temps :
  1. Thread 1 : int w = m_writePos; -> m_writePos vaut 0, donc w vaut 0
  2. Thread 2 : int w = m_writePos; -> m_writePos vaut 0, donc w vaut 0
  3. Thread 2 : if (w >= size) return false; -> On considère qu'on ne dépasse pas size, donc on ne retourne pas false
  4. Thread 2 : m_items[w] = item; -> m_items[0] vaut itemX
  5. Thread 1 : if (w >= size) return false; -> On considère qu'on ne dépasse pas size, donc on ne retourne pas false
  6. Thread 1 : m_items[w] = item; -> m_items[0] vaut itemY -> On a écrasé la valeur itemX à la position m_items[0].


C'est moi ou bien y a un problème ?

Citation Envoyé par germinolegrand  Voir le message
Et côté pédagogique, il faut par ailleurs justement marteler que les volatile n'ont rien à voir avec l'atomicité car c'est une croyance ancrée par VC++ qui n'était ainsi pas conforme au standard.

Je ne comprenais pas non plus pourquoi j'avais cette croyance entre volatile et atomicité, ça devait venir de là
0  1