c++ - 在 C++AMP 的 parallel_for_each 中使用用户指定的函数

标签 c++ templates c++11 concurrency c++-amp

我目前正在编写一个库,我希望能够允许用户定义一个函数(声明为restrict(amp))并允许他们传递这个函数在 concurrency::parallel_for_each 循环中使用我的库函数之一。例如:

template <typename T, typename Func>
void Foo( const concurrency::array_view<const T>& avParam, Func f ) 
{
     concurrency::array<T, 1> arrResult( avParam.extent );
     concurrency::parallel_for_each( avParam.extent, [=, &arrResult]( concurrency::index<1> index ) restrict(amp) {
          arrResult[index] = f( avParam[index] );
     } );

     // Do stuff...
}

如果 f 被声明为有效的 AMP 兼容函数,我希望它能工作,就好像我直接用函数本身替换函数指针 f核心;一切都按预期工作。但是,使用 f 会导致以下错误:

Function pointer, function reference, or pointer to member function is not supported.

有什么方法可以在不阻止我的用户使用 lambda 以外的仿函数的情况下实现我想要的行为?

最佳答案

References and pointers (to a compatible type) may be used locally but cannot be captured by a lambda. Function pointers, pointer-to-pointer, and the like are not allowed; neither are static or global variables.

Classes must meet more rules if you wish to use instances of them. They must have no virtual functions or virtual inheritance. Constructors, destructors, and other non-virtual functions are allowed. The member variables must all be of compatible types, which could of course include instances of other classes as long as those classes meet the same rules. The actual code in your amp-compatible function is not running on a CPU and therefore can’t do certain things that you might be used to doing:

  • recursion
  • pointer casting
  • use of virtual functions
  • new or delete
  • RTTI or dynamic casting

您应该根据仿函数的 lambda 来编写您的库,因为这些可以通过 restrict(amp) 内核访问。您可以执行以下操作:

template <typename T, typename Func>
void Foo(const concurrency::array_view<const T>& avParam, Func f)
{
    concurrency::array<T, 1> arrResult(avParam.extent);
    concurrency::parallel_for_each(avParam.extent, [=, &arrResult](concurrency::index<1> index) restrict(amp) 
    {
        arrResult[index] = f(avParam[index]);
    });

    // Do stuff...
}

template <typename T>
class Bar
{
public:
    T operator()(const T& v) const restrict(amp)
    {
        return v + 2;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<int> result(100, 0);
    array_view<const int, 1> result_av(result.size(), result);

    Foo(result_av, Bar<int>());

    return 0;
}

思考这个问题的一种方法是,仿函数或 lambda 等价物创建一个容器,编译器可以确保它没有依赖关系,并且 C++ AMP 运行时可以在 GPU 上实例化。这将很难用函数指针实现。

关于c++ - 在 C++AMP 的 parallel_for_each 中使用用户指定的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24907901/

相关文章:

c++ - 如何创建一个节点类,该节点类带有指向我可以设为 null 的父节点的指针

c++ - 如何在不声明C/C++附加功能的情况下对代码进行重复数据删除?

c++ - 基于继承关系的模板友情

c++ - 什么时候在 `std::move()` 函数中调用 move 构造函数?

c++ - C++避免重复声明的语法是什么?

c++ - 验证模板参数是其他定义的模板

c++ - 找出几个对象的最大尺寸以放置新的

c++ - 为什么 SFINAE 不能跨多重继承工作?

c++ - 令人惊讶的是, vector <char> 的自定义分配器效率低下

c++ - 如何在 C++ 中显式实例化模板构造函数?