我在看一个涉及在线(流媒体)数据的项目。我想使用该数据的滑动窗口。例如,假设我想在我的向量中保存10个值。当值11进入时,我想删除值1,将所有内容移位,然后将值11放在值10的位置。
漫长的道路如下:
int n = 9;
thrust::device_vector<float> val;
val.resize(n+1,0);
// Shift left
for(int i=0; i != n-1; i++){
val[i] = val[i+1];
}
// add the new value to the last position
val[n] = newValue;
有推力的“快速”方式吗?我正在研究的项目将有大约500个向量,需要同时完成此操作。
谢谢!
答案 0 :(得分:2)
正如我所说,Ring buffer是你所需要的。无需转移,只需一个计数器和一个固定大小的阵列。
让我们考虑如何处理500个环形缓冲区。
如果你想拥有500个(让它是512个)滑动窗口并在GPU上处理它们,那么你可以将它们打包成一个大的2D纹理,其中每列都是同一时刻的样本数组。 / p>
如果您同时为每个矢量获取新样本(我的意思是在一个处理步骤中每个512个缓冲区有一个新样本),那么这个“环纹理”(如圆柱体)只需要更新一次(在每一步上传新样本数组),您只需要一个计数器。
答案 1 :(得分:2)
我强烈建议您使用另一个但仍然免费的库来解决此问题。在4行ArrayFire代码中,您可以执行所有500个向量,如下所示:
array val = array(window_width, num_vectors);
val = shift(val, 0, 1);
array newValue = array(1,num_vectors);
val(span,end) = newValue;
我对Thrust代码进行了基准测试,并且ArrayFire的速度比Thrust提高了10倍。
缺点是ArrayFire不是开源的,但它仍然可以解决这类问题。
答案 2 :(得分:1)
想要的只是thrust::copy
。您不能并行执行转换,因为您无法保证在写入值之前读取值。
int n = 9;
thrust::device_vector<float> val_in(n);
thrust::device_vector<float> val_out(n+1);
thrust::copy(val_in.begin() + 1, val_in.end(), val_out.begin());
// add the new value to the last position
val_out[n] = newValue;