Mesurer le temps d'exécution d'OpenCL noyaux
J'ai la boucle suivante, qui mesure le temps de mes noyaux:
double elapsed = 0;
cl_ulong time_start, time_end;
for (unsigned i = 0; i < NUMBER_OF_ITERATIONS; ++i)
{
err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global, NULL, 0, NULL, &event); checkErr(err, "Kernel run");
err = clWaitForEvents(1, &event); checkErr(err, "Kernel run wait fro event");
err = clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_START, sizeof(time_start), &time_start, NULL); checkErr(err, "Kernel run get time start");
err = clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_END, sizeof(time_end), &time_end, NULL); checkErr(err, "Kernel run get time end");
elapsed += (time_end - time_start);
}
Puis-je diviser elapsed
par NUMBER_OF_ITERATIONS
pour obtenir l'estimation finale. Cependant, je crains que le temps d'exécution de l'individu noyaux est trop petite et, par conséquent, peut introduire de l'incertitude dans ma mesure. Comment puis-je mesurer le temps pris par tous les NUMBER_OF_ITERATIONS
grains combinés?
Pouvez-vous proposer un outil de profilage, ce qui pourrait aider à cela, que je n'ai pas besoin d'accéder à ces données par programmation. J'utilise NVIDIA OpenCL.
Vous devez vous connecter pour publier un commentaire.
vous devez suivre les prochaines étapes pour mesurer le temps d'exécution d'OpenCL temps d'exécution du noyau:
1.Créer une file d'attente, le profilage besoin d'été à activer lors de la file d'attente est créée:
2.Lien un événement lors de lancement d'un noyau
3.Attendez que le noyau de finir
4.Attendez que tous en file d'attente des tâches pour terminer
5.Obtenir des données de profilage et de calculer le temps d'exécution du noyau (retourné par l'API OpenCL en nanosecondes)
Le profilage de la fonction renvoie nano secondes, et est très précis (~50ns), cependant, l'exécution a différents temps de l'exécution, selon d'autres problèmes mineurs, vous ne pouvez pas contrôler.
Cela réduit votre problématique sur ce que vous voulez mesurer:
Mesurer le temps d'exécution du noyau: Votre approche est correcte, la précision de la moyenne des temps d'exécution mesuré augmentera à mesure que vous augmentez N., Ce qui représente seulement pour le temps d'exécution, pas de frais généraux à prendre en considération.
Mesurer le temps d'exécution du noyau + frais généraux: Vous devez utiliser les événements ainsi que de mesurer depuis CL_PROFILING_COMMAND_SUBMIT, pour prendre en compte supplémentaire de l'exécution de frais généraux.
La mesure de la véritable hôte de côté le temps d'exécution: Vous devez utiliser les événements ainsi que de mesurer depuis la première de début de l'événement, le dernier événement de la fin. À l'aide du PROCESSEUR le chronométrage est une autre possibilité. Si vous voulez mesurer cela, vous devez supprimer le waitforevents à partir de la boucle, afin de permettre au maximum de la capacité de traitement du système OpenCL (et moins de charge possible).
De répondre à la question des Outils, je vous conseille d'utiliser nVIDIA visual profiler. Mais depuis n'est plus disponible pour OpenCL, vous devez utiliser le complément Visual Studio ou une ancienne version (CUDA 3.0) de la nvprofiler.
Le temps mesuré est retourné en nanosecondes, mais vous avez raison: La résolution de la minuterie est plus faible. Cependant, je me demande quel est le véritable temps d'exécution de votre noyau est quand vous dites que le temps est trop court pour mesurer avec précision (mon sentiment est que la résolution doit être de l'ordre de quelques microsecondes).
Le moyen le plus approprié de mesurer le temps total de plusieurs itérations dépend de ce que "plusieurs" signifie ici. Est
NUMBER_OF_ITERATIONS=5
ouNUMBER_OF_ITERATIONS=500000
? Si le nombre d'itérations est "grand", vous pouvez simplement utiliser l'horloge système, éventuellement avec les OS des fonctions spécifiques commeQueryPerformanceCounter
sur windows (voir aussi, par exemple, Est-il un moyen de mesurer le temps jusqu'à micro-secondes à l'aide d'bibliothèque C standard? ), mais bien sûr, la précision de l'horloge système peut être inférieur à celui de l'OpenCL appareil, donc si cela fait sens vraiment dépend du nombre d'itérations.Il est dommage que NVIDIA retiré OpenCL soutien de leurs Visual Profiler, mais...
NUMBER_OF_ITERATIONS
est arbitraire vraiment. Pour l'instant j'ai été en utilisant 30. J'ai besoin d'un bon nombre à se débarrasser des erreurs.Sur Intel OpenCL mise en œuvre du GPU j'ai eu du succès avec votre approche (timing par noyau) et préfère pour le dosage d'un flux de NDRanges.
Une autre approche consiste à exécuter N fois avec et de mesurer le temps avec des marqueurs d'événements comme dans l'approche proposée dans cette question (la question n'est pas la réponse).
Fois pour de courtes grains sont généralement au moins de quelques microsecondes royaume dans mon expérience.
Vous pouvez vérifier la résolution du timer à l'aide de clGetDeviceInfo avec CL_DEVICE_PROFILING_TIMER_RESOLUTION (par exemple, 80 ns sur ma configuration).