2013-05-01 13 views
6

Czy ktoś wie, jak sprawdzić, czy kod działa na GPU lub procesorze za pomocą Cuda?Sprawdź, czy kod działa na GPU lub procesorze

__device__ __host__ double count_something(double variable) { 
    if (RUN_ON_GPU) { 
    use_cuda_variables(); 
    } else { 
    use_cpu_variables(); 
    } 
} 

Odpowiedz

11

Nie ma sposobu, aby Runtime czeku architektura kawałek kodu jest uruchomiony, ale nie ma też potrzeby, aby wiedzieć, bo to może być ustalona w czasie kompilacji i obchodzić się odpowiednio. nvcc definiuje kilka symboli preprocesora, które mogą być używane do analizowania trajektorii kompilacji podczas kompilacji kodu. Kluczowym symbolem jest __CUDA_ARCH__, który nigdy nie jest zdefiniowany podczas kompilowania kodu hosta i zawsze definiowany podczas kompilowania kodu urządzenia.

Więc to jest możliwe, aby napisać funkcję tak:

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

który będzie emitował inny kod w zależności od tego, czy jest kompilowane dla GPU lub hosta. Możesz przeczytać bardziej szczegółową dyskusję na temat sterowania kompilacją w sekcji Stack Overflow question lub w sekcji C language extensions przewodnika programowania CUDA.

+0

To nie jest w pełni poprawne. W niektórych przypadkach ten kod nie działa - spędziłem dużo czasu na debugowaniu, zanim znalazłem rozwiązanie. – avtomaton

+0

@avtomaton: Co nie jest poprawne? W jaki sposób debugowanie pasuje do tego, co jest efektywnym właśnie kodem preprocesora C++? – talonmies

+1

To nie jest w pełni poprawne. W niektórych przypadkach ten kod nie działa - spędziłem dużo czasu na debugowaniu, zanim znalazłem rozwiązanie. '__CUDA_ARCH__' może być zdefiniowany nawet w kodzie hosta, ale w takim przypadku jest zdefiniowany jako 0. Zatem właściwe sprawdzanie jest mniej więcej tak: '__device__ __host__ funkcja pływak (float x) { #if (określone (__ CUDA_ARCH__) && (__CUDA_ARCH__> 0)) powrotu 10.0f * __sinf (x); #else // kod hosta tutaj #endif } ' – avtomaton

2

Nie mogę dodać odpowiedniego oznaczenia kodu w komentarzach - postanowiłem dodać pełną odpowiedź. Definiowanie sprawdzania nie jest w pełni poprawne. W niektórych przypadkach ten kod nie działa - spędziłem dużo czasu na debugowaniu, zanim znalazłem rozwiązanie (dokumentacja CUDA nie ma o tym żadnej wzmianki).
__CUDA_ARCH__ może być zdefiniowany nawet w kodzie hosta, ale w takim przypadku jest zdefiniowany jako 0. Tak więc prawidłowe sprawdzenie jest następujące:

__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 
} 
Powiązane problemy