Latence d’access à la mémoire de l’UC des données allouées avec malloc () et cudaHostAlloc () sur Tegra TK1

J’effectue un test simple qui compare le temps de latence d’access aux données allouées avec malloc () et les données allouées avec cudaHostAlloc () à partir de l’hôte (le processeur exécute les access). J’ai remarqué que l’access aux données allouées avec cudaHostAlloc () est beaucoup plus lent que l’access aux données allouées avec malloc () sur le Jetson Tk1.

Ce n’est pas le cas pour les GPU discrets et semble uniquement applicable à TK1. Après quelques investigations, j’ai trouvé que les données allouées avec cudaHostAlloc () sont mappées en mémoire (mmap) dans les zones / dev / nvmap de l’espace d’adressage du processus. Ce n’est pas le cas pour les données malloc’d normales qui sont mappées sur le segment de processus. Je comprends que ce mappage peut être nécessaire pour permettre au GPU d’accéder aux données, car les données de cudaHostAlloc’d doivent être visibles à la fois de l’hôte et du périphérique.

Ma question est la suivante: D’où vient la surcharge d’access aux données de cudaHostAlloc provenant de l’hôte? Les données sont-elles associées à / dev / nvmap non mises en cache sur les caches de processeur?

Je crois avoir trouvé la raison de ce comportement. Après d’autres investigations (en utilisant les événements de trace Linux et en regardant le code du pilote nvmap ), j’ai trouvé que la source de la surcharge provient du fait que les données allouées avec cudaHostAlloc() sont marquées “uncacheable” à l’aide de l’indicateur NVMAP_HANDLE_UNCACHEABLE . Un appel à pgprot_noncached() est effectué pour s’assurer que les PTE pertinents sont marqués comme étant non codables.

Le comportement des access hôte aux données allouées à l’aide de cudaMallocManaged() est différent. Les données seront mises en cache (en utilisant le drapeau NVMAP_HANDLE_CACHEABLE ). Par conséquent, l’access à ces données à partir de l’hôte équivaut aux données malloc()'d . Il est également important de noter que le runtime CUDA ne permet pas aux périphériques (GPU) d’accéder aux données allouées avec cudaMallocManaged() même temps que l’hôte, et une telle action générerait un segfault. Le moteur d’exécution permet toutefois d’accéder simultanément aux cudaHostAlloc()'d de cudaHostAlloc()'d à la fois sur le périphérique et sur l’hôte, et je pense que c’est l’une des raisons pour lesquelles les données de cudaHostAlloc()'d peuvent être désactivées.