Le nvidia rdma gpudirect fonctionne-t-il toujours uniquement des adresses physiques (dans l'espace d'adresse physique du CPU)?

StackOverflow https://stackoverflow.com/questions/19841815

Question

Comme nous le savons: http://en.wikipedia.org/wiki/iommu#advantages

La pagination de mémoire périphérique peut être prise en charge par un Iommu. Un périphérique utilisant l'extension PRI-SIG PCIE Address Translation Services (ATS) Interface (PRI) peut détecter et signaler le besoin de services de gestion de mémoire.

enter image description here

Mais lorsque nous utilisons NVIDIA GPU avec CUDA> = 5.0, nous pouvons utiliser RDMA GPUDIRECT, et savoir que:

http://docs.nvidia.com/cuda/gpudirect-rdma/index.html#how-gpudirect-rdma-works

Traditionnellement, des ressources comme les fenêtres de barres sont mappées à l'espace d'adressage utilisateur ou du noyau à l'aide des adresses MMU du CPU en tant qu'E / S mappées de mémoire (MMIO). Cependant, parce que parce que Les systèmes d'exploitation actuels n'ont pas de mécanismes suffisants pour échanger des régions MMIO entre les conducteurs, le pilote du noyau NVIDIA exporte des fonctions pour effectuer les traductions et mappages d'adresse nécessaires.

http://docs.nvidia.com/cuda/gpudirect-rdma/index.html#supported-systems

RDMA pour gpudirect s'appuie actuellement sur toutes les adresses physiquesétant le même du point de vue des périphériques PCI. Cela le rend incompatible avec IOMMUS et ils doivent donc être désactivés pour RDMA pour que GPuDirect fonctionne.

Et si nous allons et mappons le processeur à l'UVA, comme ici:

#include <iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

int main() {
    // Can Host map memory
    cudaSetDeviceFlags(cudaDeviceMapHost);  

    // Allocate memory
    unsigned char *host_src_ptr = NULL;
    cudaHostAlloc(&host_src_ptr, 1024*1024, cudaHostAllocMapped);
    std::cout << "host_src_ptr = " << (size_t)host_src_ptr << std::endl;

    // Get UVA-pointer
    unsigned int *uva_src_ptr = NULL;
    cudaHostGetDevicePointer(&uva_src_ptr, host_src_ptr, 0);
    std::cout << "uva_src_ptr  = " << (size_t)uva_src_ptr << std::endl;

    int b;  std::cin >> b;
    return 0;
}

Nous obtenons des pointeurs égaux dans Windwos7x64, cela signifie que cudaHostGetDevicePointer() ne fais rien:

host_src_ptr = 68719476736

uva_src_ptr = 68719476736

Qu'est-ce que cela signifie "des mécanismes suffisants pour échanger des régions MMIO entre les pilotes", quel mécanisme est ici, et pourquoi je ne peux pas utiliser IOMMU en utilisant l'adresse virtuelle pour accéder via PCIe à la région physique de BAR - un autre appareil mappé de mémoire via PCIe ?

Et cela signifie-t-il que le RDMA GPuDirect ne fonctionne toujours que des adresses physiques (dans l'espace d'adresse physique du CPU), mais pourquoi nous envoyons à la fonction du noyau uva_src_ptr qui est égal à host_src_ptr - Pointeur simple dans l'espace d'adressage virtuel du CPU?

Était-ce utile?

La solution

L'IOMMU est très utile en ce qu'il fournit un ensemble de registres de cartographie. Il peut organiser n'importe quelle mémoire physique pour apparaître dans la plage d'adresses accessible par un appareil, et il peut également faire en sorte que les tampons diffusés physiquement soient également contigus aux appareils. Ce n'est pas bon pour les cartes PCI / PCI d'expression tierce réellement accéder aux régions de mémoire prévues ou inhiber / restreindre ces accès par carte par l'unité IOMMU. Cela doit être désactivé, alors, car

"RDMA pour gpudirect compte actuellement Toutes les adresses physiques étant les mêmes du point de vue des appareils PCI."

-Nvidia, Considérations de conception pour RDMA et GPUDIRECT

Lorsque les conducteurs tentent d'utiliser les régions MMU et MAP du CPU des E / S mappées de mémoire (MMIO) pour une utilisation dans l'espace du noyau, ils gardent généralement l'adresse retournée de la mappage de mémoire à elles-mêmes. Parce que chaque pilote fonctionne dans son propre contexte ou espace de noms, échanger ces mappages entre les pilotes de Nvidia et les autres pilotes du Vendeur tiers qui souhaitent prendre en charge RDMA + GPUDIRECT serait très difficile et entraînerait une solution spécifique au fournisseur (peut-être même le produit -Le spécifique si les conducteurs varient considérablement entre les produits du tiers). De plus, les systèmes d'exploitation d'aujourd'hui n'ont actuellement aucune bonne solution pour l'échange de mappages MMIO entre les pilotes, ainsi NVIDIA exporte plusieurs fonctions qui permettent aux pilotes tiers d'accéder facilement à ces informations à partir de l'espace de noyau, lui-même.

NVIDIA applique l'utilisation de «l'adressage physique» pour accéder à chaque carte via RDMA pour gpudirect. Cela simplifie considérablement le processus de déplacement des données d'un ordinateur vers le bus PCI-Express d'un système distant en utilisant le schéma d'adressage physique de cette machine sans avoir à se soucier des problèmes liés à l'adresse virtuelle (par exemple, résoudre les adresses virtuelles à celles physiques). Chaque carte a une adresse physique à laquelle il réside et est accessible à ce décalage; Seule un petit morceau de logique doit être ajouté au pilote tiers, tentant d'effectuer des opérations RDMA. De plus, ces registres d'adresse de base 32 ou 64 bits font partie de l'espace de configuration PCI standard, de sorte que l'adresse physique de la carte pourrait facilement être obtenue en lisant simplement à partir de sa barre plutôt que d'avoir à obtenir une adresse mappée que le pilote de Nvidia a obtenu Lors de la connexion à la carte. L'adressage virtuel universel de Nvidia (UVA) s'occupe des mappages d'adresses physiques susmentionnés à une région de mémoire apparemment continu pour espace utilisateur applications, comme ainsi:

CUDA Virtual Address Space

Ces régions de mémoire sont divisées en trois types: CPU, GPU et libre, qui sont tous documentés ici.

Retour à votre cas d'utilisation, cependant: puisque vous êtes espace utilisateur, vous n'avez pas accès direct à l'espace d'adressage physique du système, et les adresses que vous utilisez sont probablement des adresses virtuelles qui vous sont fournies par l'UVA de NVIDIA. En supposant qu'aucune allocation précédente n'ait été faite, votre allocation de mémoire doit résider au décalage + 0x00000000, ce qui vous amènerait à voir le même décalage du GPU lui-même. Si vous deviez allouer un deuxième tampon, j'imagine que vous verriez ce tampon commencer immédiatement après la fin du premier tampon (au décalage + 0x00100000 de la base adresse virtuelle du GPU dans votre cas d'allocations de 1 Mo).

Si tu étais espace de noyau, Cependant, et rédigeait un pilote pour que la carte de votre entreprise utilise le RDMA pour GPuDirect, vous utiliseriez les adresses physiques 32 ou 64 bits attribuées au GPU par le BIOS et / ou le système d'exploitation du système aux données RDMA directement vers et depuis le GPU, lui-même.

De plus, il peut être utile de noter que tous les moteurs DMA ne prennent pas en charge les adresses virtuelles pour les transferts - en fait, la plupart nécessitent des adresses physiques, car la gestion de l'adresse virtuelle d'un moteur DMA peut devenir complexe (Page 7), donc de nombreux moteurs DMA manquent de soutien à cela.

Pour répondre à la question du titre de votre message, cependant: NVIDIA ne prend actuellement en charge que l'adresse physique pour RDMA + GPUDIRECT dans l'espace de noyau. Pour espace utilisateur Applications, vous utiliserez toujours l'adresse virtuelle du GPU qui vous est donné par l'UVA de NVIDIA, qui est dans l'espace d'adresse virtuel du CPU.


Concernant votre application, voici une ventilation simplifiée du processus que vous pouvez faire pour les opérations RDMA:

  1. Ton espace utilisateur L'application crée des tampons, qui sont dans la portée de l'espace d'adressage virtuel unifié fourni par Nvidia (adresses virtuelles).
  2. Faire un appel à cuPointerGetAttribute(...) pour obtenir des jetons P2P; Ces jetons concernent la mémoire dans le contexte de Cuda.
  3. Envoyez toutes ces informations à espace de noyau D'une manière ou d'une autre (par exemple IOCTL, lire / écrire est à votre chauffeur, etc.). Au minimum, vous voudrez que ces trois choses finissent dans votre espace de noyau chauffeur:
    • Les jetons P2P sont retournés par cuPointerGetAttribute(...)
    • Adresse virtuelle UVA du ou des tampons (s)
    • Taille du (s) tampon (s)
  4. Traduisez maintenant ces adresses virtuelles par leurs adresses physiques correspondantes en appelant les fonctions d'espace de noyau de Nvidia, car ces adresses sont conservées dans les tables de page de Nvidia et peuvent être accessibles avec l'exportation de Nvidia de Fonction, telles que: nvidia_p2p_get_pages(...), nvidia_p2p_put_pages(...), et nvidia_p2p_free_page_table(...).
  5. Utilisez ces adresses physiques acquises à l'étape précédente pour initialiser votre moteur DMA qui manipulera ces tampons.

Une explication plus approfondie de ce processus peut être trouvée ici.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top