cudaMemcpy trop lent
- Je utiliser cudaMemcpy()
un temps de copier exactement 1 go de données à l'appareil. Cela prend en 5.9 s. À l'inverse, il faut 5.1 s. Est-ce normal?
La fonction elle-même avons tellement de surcharge avant de le copier?
Théorique, il devrait y avoir un débit d'au moins 4 GO/s pour le bus PCIe.
Il n'y a pas de mémoire des transferts qui se chevauchent, car la Tesla C870 juste ne prend pas en charge. Un indice?
EDIT 2: mon programme de test + mise à jour des timings; j'espère qu'il n'est pas trop de choses à lire!
Le cutCreateTimer()
fonctions habitude de compiler pour moi: 'erreur: identificateur "cutCreateTimer" est indéfini " - cela pourrait être lié à l'ancien cuda version (2.0) installé sur la machine
__host__ void time_int(int print){
static struct timeval t1; /* var for previous time stamp */
static struct timeval t2; /* var of current time stamp */
double time;
if(gettimeofday(&t2, 0) == -1) return;
if(print != 0){
time = (double) (t2.tv_sec - t1.tv_sec) + ((double) (t2.tv_usec - t1.tv_usec)) / 1000000.0;
printf(...);
}
t1 = t2;
}
main:
time(0);
void *x;
cudaMallocHost(&x,1073741824);
void *y;
cudaMalloc(&y, 1073741824);
time(1);
cudaMemcpy(y,x,1073741824, cudaMemcpyHostToDevice);
time(1);
cudaMemcpy(x,y,1073741824, cudaMemcpyDeviceToHost);
time(1);
Affiche horaires sont:
0.86 l'affectation s
0.197 s de la première copie
5.02 deuxième copie
La chose étrange est: Bien qu'il affiche 0.197 s pour la première copie, il prend beaucoup plus de temps si je regarde le programme de fonctionner.
décrit le calendrier de la modifier
OriginalL'auteur Callahan | 2011-09-15
Vous devez vous connecter pour publier un commentaire.
Oui, C'est normal.
cudaMemcpy()
fait beaucoup de contrôles et de travaux (si hôte de la mémoire a été allouée par habitudemalloc()
oummap()
). Il doit vérifier que chaque page de données dans la mémoire, et de déplacer les pages (un par un) pour le pilote.Vous pouvez utiliser
cudaHostAlloc
function oucudaMallocHost
pour l'allocation de mémoire au lieu demalloc
. Il va allouer épinglé de la mémoire qui est toujours stocké dans la mémoire RAM et peut être consulté par le GPU DMA directement (plus rapidecudaMemcpy()
). Citant à partir du premier lien:Seul facteur limitant est que le montant total de épinglé la mémoire du système est limitée (pas plus de
RAM
taille; il est préférable de ne pas utiliser plus deRAM - 1Gb
):Ok le "upload" (périphérique) est tombé à 1,1 s, mais la "télécharger" (à partir de l'appareil) est encore à 5s. Est-ce normal aussi?
Est le téléchargement de Épinglé la mémoire trop?
Oui. Dans ce test, j'ai télécharger à la même mémoire que j'ai téléchargé à partir de.
Callahan, vous pouvez afficher les détails de code? les lignes avec: allocation de mémoire; téléchargement; le démarrage du noyau (et la source du noyau); le téléchargement, le temps de livraison. Le bon timing méthode pour Cuda est d'utiliser Cuda minuteurs, vérifier des exemples de code, fourni avec CUDA. Ou ici: cs.virginia.edu/~csadmin/wiki/index.php/CUDA_Support/...
OriginalL'auteur osgx
En supposant que les transferts sont chronométrés avec précision, 1.1 secondes pour un transfert de 1 GO à partir de épinglé mémoire semble lent. Êtes-vous sûr que le port PCIe est configuré à la bonne largeur? Pour une performance, vous voulez un x16 configuration. Certaines plates-formes fournissent deux fentes, l'une qui est configuré comme un x16, l'autre comme un x4. Donc, si vous machine dispose de deux fentes, vous pouvez essayer de déplacer la carte dans la fente. D'autres systèmes ont deux fentes, où vous obtenez x16 si un seul logement est occupé, mais vous obtenez deux fentes de x8 si tous les deux sont occupés. La configuration du BIOS peut aider à déterminer les emplacements PCIe sont configurés.
La Tesla C870 est plutôt une vieille technologie, mais si je me souviens bien des taux de transfert de 2 GO/s de épinglé de la mémoire devrait être possible avec ces pièces, qui a utilisé un 1er génération d'interface PCIe. Courant de Fermi-classe Gpu utilisation d'une carte PCIe gen 2 de l'interface et peut atteindre 5 GB/s pour des transferts de épinglé mémoire (pour les mesures de débit, de 1 GO/s = 10^9 octets/s).
Noter que PCIe utilise une mise en paquet de transport, et le paquet de surcharge peuvent être importants à la taille des paquets pris en charge par la commune des chipsets, avec les nouveaux chipsets généralement de soutenir un peu plus les paquets. On est peu probable de les dépasser 70% de la valeur nominale par la direction maximum (4 GO/s, PCIe 1.0 x16, 8 GO/s, PCIe 2.0 x16), de même pour les transferts de /vers l'épinglé de la mémoire hôte. Voici un livre blanc qui explique la surcharge problème et a une pratique graphique montrant l'utilisation réalisable avec différentes tailles de paquets:
http://www.plxtech.com/files/pdf/technical/expresslane/Choosing_PCIe_Packet_Payload_Size.pdf
Malheureusement je ne vais pas ni la machine, ni dans le bios, car il est éloigné de celui que je suis en train de travailler sur.
OriginalL'auteur njuffa
Autre qu'un système qui n'est tout simplement pas configuré correctement, la meilleure explication de la terrible PCIe de la bande passante d'un conflit entre les IOH/socket et le logement PCIe que le GPU est branchée sur.
La plupart des multi-socket Intel i7-classe (Nehalem, Westmere) les cartes mères ont un I/O hub par socket. Depuis la mémoire système est directement relié à chaque PROCESSEUR, DMA accède aux que sont "locales" (de l'extraction de la mémoire de la CPU connectés à la même IOH que le GPU fait l'accès DMA) sont beaucoup plus rapide que les non locaux (de l'extraction de la mémoire de la CPU connecté à l'autre IOH, une opération qui doit être satisfaite par le QPI d'interconnexion qui relie les deux Processeurs).
REMARQUE IMPORTANTE: malheureusement, il est commun pour les SBIOS pour configurer des systèmes pour l'entrelacement, ce qui provoque les allocations de mémoire contiguë à être intercalée entre les prises. Cela réduit les performances des falaises de locaux/d'accès non locaux pour les Cpu (une façon de penser: il rend tous les accès à la mémoire aussi mauvais pour les deux sockets), mais fait des ravages avec GPU accès aux données car elle provoque de toutes les autres pages sur socket 2 système à être locale.
Nehalem et Westmere les systèmes de classe ne semblent pas souffrir de ce problème si le système ne dispose que d'une IOH.
(Sandy Bridge processeurs de la classe de prendre une autre étape dans cette voie en intégrant le support de PCI Express dans la CPU, donc avec Sandy Bridge, multi-socket machines automatiquement plusieurs IOH.)
Vous pouvez vérifier cette hypothèse par l'exécution de votre test à l'aide d'un outil que les broches à une prise (numactl sur Linux, si elle est disponible) ou à l'aide de la plate-forme dépendante de code pour piloter les allocations et les threads de s'exécuter sur un socket spécifique. Vous pouvez en apprendre beaucoup sans obtenir de fantaisie et appeler une fonction avec des effets globaux au début de main() pour forcer le tout sur une prise ou d'une autre, et voir si cela a un gros impact sur votre PCIe performances de transfert.
cudaSetDevice(0);
au début comme un "effet global de la fonction". Les Timings n'ont pas changé.OriginalL'auteur ArchaeaSoftware