2016-07-07 54 views
1

我有一个模板(CUDA,虽然适用于C++)函数(我已经简化以使点)如下:“毫无意义的比较”警告在模板与某些值

template<unsigned windowsize> 
__global__ void someFunc() 
{ 
    if (threadIdx.x < (32 - windowsize * 2)) 
    { 
     // ... something exciting 
    } 
} 

我使用“windowsize”代码设置为1-16。的Visual Studio 2013中使用nvcc编译,我得到以下警告:

warning : pointless comparison of unsigned integer with zero 

这显然是针对情况下windowsize = 16(针对if语句的计算结果为threadIdx.x < 0,也就是假的),所以警告确实有道理。

我看过类似的问题: How to silence a particular "pointless comparison of unsigned with zero" warning?但这是在使用typedef而不是模板,所以答案不适合的情况。

有没有更好的方法来构建这个功能,它将提供相同的功能,而不会有警告?我可以创建单独的函数来处理windowsize大于和小于16的不同,但实际上函数更复杂,我觉得我不必要地重复并且使代码复杂化,这是使用模板开始的全部要点用。

回答

1

您可以尝试专业的模板功能,16:

template<unsigned windowsize> 
__global__ void someFunc() 
{ 
    //... 
    std::cout << "called for windowsize " << windowsize << '\n'; 
} 

template<> 
__global__ void someFunc<16>() 
{ 
    //... 
    std::cout << "specialized for windowsize 16" << '\n'; 
} 

void foo() 
{ 
    someFunc<4>(); 
    someFunc<16>() 
} 

Live example

如果有共同的代码,那么您可以出来,并创建一个单独的功能,无论是正规和专业版会呼叫。

2

最明显的方法是因素比较成一个单独的函数:

template <unsigned WindowSize> 
bool doSomethingExciting() { return threadIdx.x < (32u - WindowSize * 2u); } 
template <> 
bool doSomethingExciting<16>() { return false; } 

template<unsigned windowsize> 
__global__ void someFunc() 
{ 
    if (doSomethingExciting<windowsize>()) 
    { 
     // ... something exciting 
    } 
} 
+1

虽然这解决了这个问题,它是编译器已经为我做的事情的额外代码行。 – valjean

0

您可能要进行两次测试,其中首先应在编译时进行:

template<unsigned windowsize> 
__global__ void someFunc() 
{ 
    if (windowsize < 16) 
    { 
     if ((int)threadIdx.x < (int)(32 - windowsize * 2)) 
     { 
      // ... something exciting 
     } 
    } 
} 
+0

我有一个包装函数,它使用std :: enable_if来检查windowsize <16(无法让它与__global__ void一起工作),但是转换为int可能是一个不错的解决方案。 – valjean