2013-05-01 3 views

ответ

11

Там нет никакого способа выполнения проверки, какая архитектура кусок кода работает, но там также нет необходимости знать, потому что это может быть определено во время компиляции и обрабатывается соответствующим образом. nvcc определяет несколько символов препроцессора, которые могут использоваться для синтаксического анализа траектории компиляции во время компиляции кода. Символом ключа является __CUDA_ARCH__, который никогда не определяется при компиляции кода хоста и всегда определяется при компиляции кода устройства.

Так что можно написать функцию так:

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

, который будет излучать разный код в зависимости от того, является ли она составлена ​​для графического процессора или хоста. Вы можете прочитать более подробное обсуждение компиляции рулевого управления в этом Stack Overflow question или в разделе C language extensions руководства по программированию CUDA.

+0

Это не совсем правильно. В некоторых случаях этот код не работает - я потратил много времени на отладку, прежде чем нашел решение. – avtomaton

+0

@avtomaton: Что не так? Как отладка вписывается в то, что фактически является только препроцессорным кодом C++? – talonmies

+1

Это не совсем правильно. В некоторых случаях этот код не работает - я потратил много времени на отладку, прежде чем нашел решение. '__CUDA_ARCH__' может быть определен даже в главном коде, но в этом случае он определен как 0. Таким образом, правильная проверка что-то вроде этого: '__device__ __host__ поплавка функция (флоат х) { #if (определение (__ CUDA_ARCH__) && (__CUDA_ARCH__> 0)) возвращение 10.0f * __sinf (х); #else // код хозяина здесь #endif } ' – avtomaton

2

Я не могу добавить правильную уценку кода в комментариях - решил добавить полный ответ. Использование только __CUDA_ARCH__ Определить проверку не удалось. В некоторых случаях этот код не работает - я потратил много времени на отладку, прежде чем нашел решение (документация CUDA не упоминает об этом сейчас).
__CUDA_ARCH__ может быть определен даже в главном коде, но в этом случае он определен как 0. Таким образом, надлежащая проверка выглядит примерно так:

__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 
} 
Смежные вопросы