表达式模板 + CRTP + AMP == 内核生成

Expression Templates + CRTP + AMP == kernel generation

本文关键字:内核 CRTP 表达式 AMP      更新时间:2023-10-16

我最近发现了表达式模板的绝对棒性,并且在使用它们方面的理解和技能达到了令人满意的水平,但是我想重新使用这个成语。我会跳过关于我如何解决这个问题的冗长故事,但这个问题在价值方面证明了自己。

我正在尝试创建与 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。这完全破坏了表达式 Tempalte 习语(此处可能使用了错误的单词(,其中操作相互打包,并且它们都包含对内部操作数的引用。按值存储 AFAIK 也不是一种选择,因为编译器只"透视"没有(const(引用以外的成员的类。

有没有办法做到这一点,或者找到一些完全主机端C++的替代路由,并在以后的某个时候全部转换为 C++AMP 兼容结构?最终,我希望能够制作包装类,没有任何GPGPU知识的人可以有效地使用,而无需我创建代码生成工具,而不是让编译器进行所有艰苦的工作。

提前谢谢。

PS.:当然index_type是并发::INDEX<1>container_type是并发::数组或并发::array_view,以有助于解决问题为准。 array_view在逻辑上更干净,这意味着 Vec 类是使用类外部的数组创建的,Vec 仅将array_views存储到该数组中,但不允许array_views以任何形式作为引用成员, 此外,逻辑数组应该允许编译器进行更多优化,而不是让每个操作在不同的array_views上运行,这些操作实际上可能指向同一个物理数组。

如果有人遇到这个非常过时的问题,我找到了解决最初问题的方法。

与其使用带有引用语义的表达式模板,不如使用值语义并使用array_view实例来引用数据,而不是const array&