C ++标准库使用以下代码实现std::copy
(忽略所有类型的包装和概念检查等)和简单的循环:
for (; __first != __last; ++__result, ++__first)
*__result = *__first;
现在,假设我想要一个用于warp(而不是块;而不是网格)的通用std::copy
函数来用于协同地将数据从一个地方复制到另一个地方。我们甚至假设该函数采用指针而不是任意迭代器。
当然,在CUDA中编写通用代码通常是一种无用的追求 - 因为我们可能首先牺牲使用GPU的许多好处而支持通用性 - 所以我将允许自己一些布尔/枚举模板可能在频繁出现的情况之间进行选择的参数,避免运行时检查。因此签名可能是:
template <typename T, bool SomeOption, my_enum_t AnotherOption>
T* copy(
T* __restrict__ destination,
const T* __restrict__ source,
size_t length
);
但是对于这些情况中的每一种情况,我都希望获得最佳性能(或者考虑到我们不知道其他经线正在做什么的最佳预期性能)。
在编写这样的函数时,我应该考虑哪些因素?换句话说:在实现这个功能时,我应该区分哪些情况?
笔记:
memcpy()
调用。至少,我不认为我这样做。我认为应该考虑的因素:
sizeof(T)
是sizeof(T)
是1或2,并且我们已经让每个通道写入单个元素,整个warp将写入小于128B,浪费一些内存事务。相反,我们应该让每个线程在寄存器中放置2或4个输入元素,然后编写它sizeof(T)
)> 4,它不是很清楚该怎么做。当每个通道写入超过4个字节时,编译器/ GPU处理写入的程度如何?我想知道。T
是否可以简单地复制构造。但我们假设它是。但可能是因为我缺少一些考虑因素,或者上述某些因素是多余的。
我一直在想的因素: