1

我正在研究一个涉及在线(流)数据的项目。我想使用该数据的滑动窗口。例如,假设我想在我的向量中保存 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 个向量需要同时完成此操作。

谢谢!

4

3 回答 3

3

正如我所说,环形缓冲区是您所需要的。无需移到那里,只需一个计数器和一个固定大小的数组。

让我们考虑一下如何处理 500 个环形缓冲区。

如果您想拥有 500 个(假设为 512 个)滑动窗口并在 GPU 上处理它们,那么您可以将它们打包成一个大的 2D 纹理,其中每一列都是同一时刻的一组样本。

如果您一次为每个向量获取新样本(我的意思是在一个处理步骤中为每个 512 个缓冲区提供一个新样本),那么这个“环形纹理”(如圆柱体)只需要更新一次(上传每个步骤中的新样本数组),您只需要一个计数器。

于 2012-07-03T08:23:44.900 回答
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 不是开源的,但对于这类问题它仍然是免费的。

于 2012-07-03T21:04:46.363 回答
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;
于 2012-07-03T12:28:12.273 回答