我最近发现了表达式模板的绝妙之处,并且对它们的使用有了一定程度的理解和技能,但是我想重新使用这个成语。我会跳过关于我如何解决这个问题的冗长故事,但这个问题在价值方面证明了自己。
我正在尝试创建与wiki上类似的基本表达式类,但采用与 C++AMP 兼容的形式,这意味着这些操作都是在 C++AMP 内核中完成的。人们可以轻松地将包装类编写到这样的大型向量操作中,这些操作将每个基本操作都作为一个单独的内核,但这是非常低效的。我正在尝试创建包装表达式模板类,最终将操作合并到一个内核中。
鉴于 wiki 上的示例代码,这意味着在 Vec 类的复制构造函数中,可以编写
concurrency::parallel_for_each(vec.get_extent(), [&](index_type i) restrict(amp,cpu) {...});
而不是常规的 for 循环。唯一的问题是,在 restrict(amp) 函数内部,只能使用与 amp 兼容的类,这些类的限制在C++AMP 规范的第 2 节中描述,最重要的是在第 2.4 节中。最大的限制是 C++AMP 兼容的类不能有引用成员,除了 concurrency::array。这完全破坏了 Expression Tempalte 习语(可能在这里使用了错误的词),其中操作彼此打包,并且它们都包含对内部操作数的引用。按值存储 AFAIK 也不是一种选择,因为编译器仅“透视”没有除 (const) 引用以外的成员的类。
有什么办法可以使这项工作,或者找到一些完全是主机端 C++ 的替代路线,并在以后的某个时间点全部转换为 C++AMP 兼容的构造?最终,我希望能够制作包装类,让没有任何 GPGPU 知识的人可以高效使用,而无需我创建代码生成工具,而不是让编译器完成所有艰苦的工作。
提前致谢。
ps.:自然 index_type 是 concurrency::index<1> 而 container_type 要么是 concurrency::array 要么是 concurrency::array_view,以有助于解决问题的为准。array_view 在逻辑上更简洁,这意味着 Vec 类是使用类外部的数组创建的,并且 Vec 仅将 array_views 存储到该数组中,但是 array_views 不允许作为任何形式的引用成员,加上逻辑上,数组应该允许更多的优化编译器,而不是让每个操作都在不同的 array_views 上运行,这实际上可能指向同一个物理数组。