Bonjour,
Je viens récemment de me mettre à OpenCL et j'essaye d'optimiser un de mes code.
Je suis cependant un peu perdu avec les variables static/private/locale/globales.
Je crois qu'il y a quelques optimisation contre-intuitives du compilateur qui me perdent un peu.
De manière générale, j'ai 4 variables en buffer global, 1 pour les résultats (write-only), et 3 pour les inputs (read-only):
- A: 1 unique pour tous les threads (const int [32]);
- B: 1 différente pour chaque threads (4 600 threads * const float [32]);
- C: 1 unique pour tous les threads de longueur variable (K * const float [32*32]) // pour le moment K < 20, à terme K potentiellement très grand (2^32);
Je sais que de manière générale, avoir ces variables dans le buffer global me plombe mes performances.
A est quelque peu troublant. J'obtiens les meilleures performances lorsque je le laisse dans le buffer global. Si je l'écris en dur dans le code de mon kernel (+17% en temps d'exécution), ou si j'essaye de le fetch en private avant usage, mes performances se dégradent. Ce qui est très troublant.
En revanche, pour B, j'ai gagné en performance en le fetchant en private avant usage.
Pour C, je ne gagne pas en performances si je le fetch en private avant usage (avec K=1).
Pour fetcher en private, je fait un bête parcours :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 int A_priv[32]; for(int i = 0; i < 32; ++i) A_priv[i] = A[i].
Je pensais les fetcher en local avant usage, mais je me demande si j'aurais réellement un gain vu que je ne fais pas d'écriture sur ces variables :
- A : j'ai l'impression que le compilateur optimise, l'utilisation est très rapide, même si j'utilise les valeurs plusieurs fois ;
- B : unique pour chaque thread, je les récupère en private ;
- C : petit (32*32) à très gros (K*32*32), le même pour tous les threads, je me demande s'il serait sage de le récupérer en local / ses valeurs ne sont utilisées qu'une seule fois chacunes.
Est-ce que vous auriez donc des conseils/best practices sur l'utilisation des buffers locaux ?
Est-ce que vous auriez une idée sur la raison pour laquelle pour A, un buffer global est plus performant que les valeurs écrites en dur dans le kernel, ou de le fetcher en private alors que je l'utilise plusieurs fois ?
Quelques informations sur ma configuration:
Using platform: Intel Gen OCL Driver
Using device: Intel(R) HD Graphics Skylake ULT GT2
Beignet: "unable to find good values for local_work_size[i], please provide\n" " local_work_size[] explicitly, you can find good values with\n" "
trial-and-error method."
En vous remerciant d'avance pour vos réponses.
Partager