2010-08-08 4 views
5

Quand j'ai commencé la programmation en OpenCL j'ai utilisé l'approche suivante pour fournir des données à mes noyaux:Gestion de la mémoire dans OpenCL

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE, object_size, NULL, NULL); 
clEnqueueWriteBuffer(cl_queue, buff, CL_TRUE, 0, object_size, (void *) object, NULL, NULL, NULL); 

Cela m'a évidemment nécessaire de cloisonner mes données en morceaux, faire en sorte que chaque morceau s'intégrerait la mémoire de l'appareil. Après avoir effectué les calculs, je lisais les données avec clEnqueueReadBuffer(). Cependant, à un moment donné, je compris que je pouvais simplement utiliser la ligne suivante:

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, object_size, (void*) object, NULL); 

Quand vous faites cela, le partage des données est devenu obsolète. Et à ma grande surprise, j'ai connu une grande amélioration de la performance. C'est quelque chose que je ne comprends pas. D'après ce que j'ai obtenu, lorsque j'utilise un pointeur hôte, la mémoire de l'appareil fonctionne comme un cache, mais toutes les données doivent encore être copiées pour le traitement et ensuite copiées dans la mémoire principale une fois terminé. Comment se fait-il que l'utilisation d'une copie explicite (clEnqueRead/WriteBuffer) soit d'un ordre de grandeur plus lent, alors que dans mon esprit, elle devrait être fondamentalement la même? Est-ce que je manque quelque chose?

Merci.

Répondre

2

Oui, il vous manque le CL_TRUE dans l'appel clEnqueueWriteBuffer. Cela rend le blocage de l'opération d'écriture, qui bloque le processeur pendant la copie. En utilisant le pointeur hôte, l'implémentation OpenCL peut "optimiser" la copie en la rendant asynchrone, donc globalement la performance est meilleure. Notez que cela dépend de l'implémentation CL, et il n'y a aucune garantie que ce soit plus rapide/égal/plus lent.

+0

Je connais l'indicateur de blocage sur clEnqueueRead/WriteBuffer. Cependant quand j'ai fait les mesures, j'ai employé un clFinish (au moins je suis sûr que je l'ai fait), qui devrait avoir le même effet que le drapeau de blocage, ou pas? C'est, bien sûr, seulement si la même quantité de données est traitée. Hm, peut-être que l'implémentation CL est assez intelligente pour laisser de côté la partie d'un objet qui n'est pas accessible (environ 70%) ... Merci quand même! – VHristov

1

Dans certains cas, la CPU et le GPU peuvent partager la même mémoire DRAM physique. Par exemple, si le bloc de mémoire satisfait aux règles d'alignement du processeur et du GPU, Intel interprète CL_MEM_USE_HOST_PTR comme une autorisation de partage de DRAM physique entre le processeur et le GPU, de sorte qu'il n'y a pas de copie réelle des données. Évidemment, c'est très rapide!

Voici un lien qui explique:

https://software.intel.com/en-us/articles/getting-the-most-from-opencl-12-how-to-increase-performance-by-minimizing-buffer-copies-on-intel-processor-graphics

PS Je sais que ma réponse est beaucoup trop vieux pour OP, mais d'autres lecteurs peuvent être intéressés.