2017-07-21 3 views
1

J'ai créé un programme qui doit appeler une fonction plusieurs fois (lots !!) avec différents paramètres d'entrée. Pour accélérer les choses, je multithread cela comme ceci:Passage du programme CPU multithread au GPU en C++

std::vector< MTDPDS* > mtdpds_list; 
boost::thread_group thread_gp; 
for (size_t feat_index = 0; feat_index < feat_parser.getNumberOfFeat(); ++feat_index) 
{ 
    Feat* feat = feat_parser.getFeat(static_cast<unsigned int>(feat_index)); 

    // != 0 has been added to avoid a warning message during compilation 
    bool rotatedFeat = (feat->flag & 0x00000020) != 0; 
    if (!rotatedFeat) 
    { 
     Desc* desc = new Desc(total_sb, ob.size()); 

     MTDPDS* processing_data = new MTDPDS(); 
     processing_data->feat = feat; 
     processing_data->desc = desc; 
     processing_data->img_info = image_info; 
     processing_data->data_op = &data_operations; 
     processing_data->vecs_bb = vecs_bb; 

     mtdpds_list.push_back(processing_data); 

     thread_gp.add_thread(new boost::thread(compute_desc, processing_data)); 
    } 
} 

// Wait for all threads to complete 
thread_gp.join_all(); 

Ce code est un morceau d'un plus grand bien du code, donc ne vous inquiétez pas trop sur les noms de variables, etc ... L'important est que je crée un objet (MTDPDS) pour chaque thread qui contient des paramètres d'entrée et de sortie, puis générer un thread appelant ma fonction de traitement compute_desc, et attendre que tous les threads soient terminés avant de continuer.

Cependant, ma boucle for a environ 2000 itérations, ce qui signifie que je commence environ 2000+ threads. Je cours mon code sur un cluster, donc c'est assez rapide, même si cela prend encore trop de temps à l'OMI.

Je voudrais déplacer cette partie vers le GPU (car il a beaucoup plus de cœurs), même si je suis nouveau dans la programmation GPU.

  1. Existe-t-il un moyen (comme j'ai déjà une fonction de calcul séparée) de déplacer facilement ceci sans changer le code entier? Comme une fonction qui pourrait démarrer des threads sur GPU de la même manière que boost (comme remplacer le thread boost avec le thread GPU)?
  2. Aussi, ma fonction informatique accède à certaines données chargées en mémoire (RAM ici), le GPU nécessite-t-il de charger ces données dans la mémoire GPU, ou peut-il accéder à RAM (et dans ce cas, lequel est plus rapide) ?
  3. Et une dernière question (même si je suis sûr que je connais la réponse), est-il possible de rendre le matériel indépendant (donc mon code pourrait fonctionner sur Nvidia, ATI, etc ...)?

Merci.

+0

Si vous avez besoin d'un support matériel qui prend en charge le multithreading, votre meilleur pari est probablement d'apprendre Vulkan. Il est beaucoup plus efficace que openGL et permet à la fois le matériel nVidia et AMD, contrairement à CUDA –

+0

D'après ce que j'ai vu, Vulkan est beaucoup plus orienté graphique que pour le calcul, n'est-ce pas? – whiteShadow

+0

oui vous avez raison, peut-être essayer de regarder dans OpenCL? –

Répondre

3
  • 1) La solution la plus simple consiste à utiliser la directive #pragma (OpenACC) qui devrait déjà être présente dans GCC7.

  • 2) vos données doivent être GPU convivial, devrait être GPU compatible comprendre la structure du tableau

  • 3) votre compute_desc « noyau », si vous ne savez pas laisser dire qu'il devrait vectorisable par le compilateur.

J'espère que cela vous aidera un peu, je pense un petit tutoriel sur OpenACC tuto si la meilleure solution pour vous, CUDA/OpenCL devrait venir plus tard. Mes 2 cents

+0

Merci pour le tutoriel. Bien que je devrais creuser dans la documentation, parce que dans mon cas, ma boucle appelle ma fonction de traitement, qui elle-même a des fonctions d'appel en boucle. Je pense qu'OpenACC 2.0 a quelque chose appelé «routine» que je pourrais utiliser, mais je n'ai toujours pas compris comment l'utiliser pour le moment. – whiteShadow