2013-05-01 14 views

risposta

11

Non v'è alcun modo per runtime controllo che l'architettura di un pezzo di codice è in esecuzione, ma c'è anche bisogno di sapere, perché può essere determinato al momento della compilazione e trattati di conseguenza. nvcc definisce diversi simboli del preprocessore che possono essere utilizzati per analizzare la traiettoria della compilazione mentre il codice è in fase di compilazione. Il simbolo della chiave è __CUDA_ARCH__ che non viene mai definito durante la compilazione del codice host e sempre definito durante la compilazione del codice dispositivo.

quindi è possibile scrivere una funzione come questa:

__device__ __host__ float function(float x) 
{ 
#ifdef __CUDA_ARCH__ 
    return 10.0f * __sinf(x); 
#else 
    return 10.0f * sin(x); 
#endif 
} 

che emetterà codice diverso a seconda che esso è stato compilato per la GPU o host. È possibile leggere una discussione più approfondita sulla sterzatura delle compilation in questo Stack Overflow question o nella sezione C language extensions della guida di programmazione CUDA.

+0

Questo non è completamente corretto. In alcuni casi questo codice non funziona - ho passato molto tempo nel debugging prima di trovare una soluzione. – avtomaton

+0

@avtomaton: cosa non è corretto? Come si adatta il debugging in ciò che è effettivamente solo il codice del preprocessore C++? – talonmies

+1

Questo non è completamente corretto. In alcuni casi questo codice non funziona - ho passato molto tempo nel debugging prima di trovare una soluzione. '__CUDA_ARCH__' può essere definito anche nel codice host, ma in tal caso è definito a 0. Così adeguato controllo è qualcosa di simile: '__device__ __host__ funzione galleggiante (float x) { #if (defined (__ CUDA_ARCH__) && (__CUDA_ARCH__> 0)) ritorno 10.0f * __sinf (x); #else // codice host qui #endif } ' – avtomaton

2

Non riesco ad aggiungere il markdown del codice corretto nei commenti - ho deciso di aggiungere una risposta completa. L'utilizzo della sola definizione di controllo __CUDA_ARCH__ non è completamente corretto. In alcuni casi questo codice non funziona - Ho passato molto tempo nel debugging prima di trovare una soluzione (la documentazione CUDA non ne parlava ora).
__CUDA_ARCH__ può essere definito anche nel codice host, ma in tal caso è definito a 0. Quindi il controllo corretto è qualcosa del genere:

__device__ __host__ float function(float x) 
{ 
#if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0)) 
    // device code here 
    return 10.0f * __sinf(x); 
#else 
    // host code here 
    return 10.0f * sin(x); 
#endif 
} 
Problemi correlati