2016-11-19 3 views
0

Supposons que jePuis-je demander à mon compilateur d'utiliser fast-math pour chaque fonction?

template <bool UsesFastMath> void foo(float* data, size_t length); 

et je veux compiler un instanciation avec -ffast-math (--use-fast-math pour nvcc), et l'autre instanciation sans elle. Ceci peut être réalisé en instanciant chacune des variantes dans une unité de traduction séparée, et en compilant chacune d'entre elles avec une ligne de commande différente - avec et sans le commutateur.

Ma question est de savoir s'il est possible d'indiquer aux compilateurs populaires (*) d'appliquer ou de ne pas appliquer -ffast-math pour des fonctions individuelles - afin que je puisse avoir mes instanciations dans la même unité de traduction.

Notes:

  • Si la réponse est "non", des points bonus pour expliquer pourquoi.
  • Ce ne sont pas les mêmes questions que this one, qui consiste à activer et désactiver le calcul rapide au moment de l'exécution. Je suis beaucoup plus modeste ...

(*) par les compilateurs populaires que je veux dire tout de: gcc, clang, msvc cpi, nvcc (pour le code du noyau GPU) dont vous avez cette information.

+1

'nvcc': Non. Les indicateurs de compilation sont appliqués par unité de compilation. Aucun attribut de fonction équivalente n'existe pour appliquer cette fonction par fonction. Si vous souhaitez appliquer différents indicateurs, collez le code dans différentes unités de compilation (vous pouvez inclure le code source du même fichier, si vous le souhaitez). Pour un contrôle local serré, divers éléments intrinsèques du dispositif CUDA (ou le pire des cas, un assemblage en ligne) peuvent fournir une grande partie de ce dont vous avez besoin. – njuffa

+0

@njuffa: Faites-en une réponse s'il vous plaît. – einpoklum

+0

J'ai fourni une réponse comme suggéré – njuffa

Répondre

2

Dans GCC, vous pouvez déclarer des fonctions comme suit:

__attribute__((optimize("-ffast-math"))) 
double 
myfunc(double val) 
{ 
    return val/2; 
} 

C'est fonction GCC seule.

Voir par exemple travailler ici ->https://gcc.gnu.org/ml/gcc/2009-10/msg00385.html

Il semble que GCC ne vérifie optimiser() arguments. Donc les fautes de frappe comme "-fast-match" seront silencieusement ignorées.

+0

"Fonction GCC seulement" - cela signifie simplement que cela ne découle d'aucune norme publique, n'est-ce pas? Ou dites-vous aussi que, disons, clang n'a pas une telle fonctionnalité? – einpoklum

1

A partir de CUDA 7.5 (la dernière version que je connais, bien que CUDA 8.0 est actuellement livré), nvcc ne fait pas attributs de la fonction de soutien qui permettent aux programmeurs d'appliquer les optimisations du compilateur spécifiques sur une base par fonction. Comme les configurations d'optimisation définies via des commutateurs de ligne de commande s'appliquent à l'ensemble de l'unité de compilation, une approche possible consiste à utiliser autant d'unités de compilation différentes que de configurations d'optimisation différentes, comme indiqué dans la question; code source peut être partagé et #include -ed à partir d'un fichier commun.

Avec nvcc, la ligne de commande commutateur --use_fast_math commande essentiellement trois zones de fonctionnement:

  • en mode de rinçage à zéro est activé (qui est, d'assistance dénormalisé est désactivé)
  • réciproque simple précision, division et racine carrée sont commutées versions approximatives
  • Certaines fonctions mathématiques standard sont remplacés par équivalent, inférieur précision,
intrinsèques

Vous pouvez appliquer certains de ces changements avec une granularité par opération en utilisant des intrinsèques appropriés, d'autres en utilisant l'assemblage en ligne PTX.

+0

C'est la même chose pour CUDA 8.0 AFAICT. – einpoklum