假设我有3d数组,其大小为[N, M, K]
的1d平面。我想像[0:N, 1:M, 0:K]
一样处理切片。
我创建了一个辅助函数,用于按切片数组中的索引处理底层数组(为简单起见,我仅按第二维切片)。
#define N somevalue
#define M somevalue
#define K somevalue
// i is an index in sliced array so we need to translate it into original one
template<class T, int FROM>
__device__ __forceinline__ T slice(const T * const __restrict__ x, const size_t i) {
auto batch_size = (M - FROM) * K;
auto batch_index = i / batch_size;
auto offset_0 = i % batch_size;
auto offset_1 = offset_0 / STATES;
auto offset_2 = offset_0 % STATES;
return x[batch_index * M * K + (offset_1 + FROM) * K + offset_2];
}
从NVidia分析器中,我看到除法和模除法需要大量的计算能力。另外,大小不是2的幂,所以我不能直接使用移位位技巧。
您有什么建议? 我知道切片是TF中很常见的操作,那么他们如何解决呢?
答案 0 :(得分:0)
Cuda涉及合并的内存访问和simd。而任意切片则完全相反。因此答案照常:取决于情况。
如果偏移量为0,并且仍然为1,则将内存布局朝MN K方向移动。如果被忽略的条目确实确实很稀疏,请采用传统方式,并仅闲置一些线程(是的,这很痛苦,但是有些threadIdx calc没有模数可能会更快)。否则,您将需要像问题中所写的那样,将这个双射映射线程/ block-id计算为element-id。
有时您需要吞咽苦药。有一些方法可以通过其他一些运算来表示模。但是通常最好花一些时间来改善内核的其他部分。