【问题标题】:take an array from a circular array从圆形数组中取一个数组
【发布时间】:2016-09-23 08:59:10
【问题描述】:

所以,我的目标是在缓冲区中捕获数据。 我需要速度,我只需要一个固定的大小,所以我认为圆形数组是最好的。

但我想做的是在每一步:

  • 首先,用刚刚到达的最新信息覆盖数组中的最新信息
  • 接下来,使用从最旧到最新的 all 数组
  • 重复

我很难理解如何在高效的同时处理 C++ 中的第二步。或者也许除了圆形数组之外的其他东西会更好?欢迎任何建议或观点。

要有更多的图形:

for step in steps:
    (current writing position = 2)
    current buffer = [8, 9, 3, 4, 5, 6, 7]

    new info = 10

    overwrite buffer(new info)
    new buffer = [8, 9, 10, 4, 5, 6, 7] 

    current writing position += 1   //(3)

    array to use = [4, 5, 6, 7, 8, 9, 10]

    function(array to use)

(我用整数一个个来看看缓冲区中每条信息的年表)

我正在考虑的是复制最后一部分和第一部分,然后将它们连接起来:

std::vector<int>   buffer{8, 9, 10, 4, 5, 6, 7};

std::vector<int>   oldest(&buffer[3],&buffer[6]);
std::vector<int>   youngest(&buffer[0],&buffer[2]);

oldest.insert( oldest.end(), youngest.begin(), youngest.end() );

function(oldest)

如果你知道什么会更快,请告诉我。

【问题讨论】:

  • 如果有人认为要理解我的问题,最好用 c++ 更改伪代码,让我知道。我会改变它。我当前的代码比这更复杂。

标签: c++ arrays queue buffer


【解决方案1】:

如果你真的需要速度,你不应该复制元素,而是使用你已经拥有的索引信息以正确的顺序访问元素。

所以处理函数只需要一个指向数组的指针(或对 std::vector 的引用),知道大小和当前工作位置。

// process from working pos to end of buffer
for(int i  = current_pos; i < buffer_size; ++i) {
   processElement(new_buffer [i]);
}
// process the remainder from begin to working pos
for(int i  = 0; i < curent_pos; ++i) {
   processElement(new_buffer [i]);
}

这应该不难实现,因为您的工作位置标记了要处理的数据的开始和结束。

【讨论】:

  • 问题是我正在使用第三方库,它的功能需要 all 数组。我不能只处理缓冲区的一个元素。
  • 函数采用哪种类型的数组?它从哪里获得尺寸信息?这意味着函数如何知道要处理多少元素?
  • 内存使用有问题吗?如果没有,有一个简单的方法可以极大地降低复制成本。
  • 它需要一个 tensorflow::tensor 作为入口。我在想首先将数据放入向量(缓冲区)中,然后用它创建张量。但现在我想我可以按照你写的那样逐个元素地填充张量元素。但我觉得效率不高。关于内存没有真正的问题。速度是主要焦点。
  • 你有张量类的文档(链接)吗?也许有一种快速的方法是在不复制的情况下分配多个值。
【解决方案2】:

这种方法减少了 n 倍的复制开销,其中 n 是使用的额外数组元素的数量 + 1。

示例:包含 2 个额外元素的数组

注意,在这种情况下,最旧的值在左边,函数被调用,指针指向 arr[0] (start_pos = 0)

arr == [3, 4, 5, 6, 7, 8, 9, x, x]

现在,让我们插入新值 10

arr == [3, 4, 5, 6, 7, 8, 9, 10, x]

start_pos += 1

使用指向第二个元素的指针调用函数(不会使用旧的 3)

function(arr + start_pos)

现在添加 11 并增加工作位置(不会使用旧的 4)

arr == [3, 4, 5, 6, 7, 8, 9, 10, 11]

start_pos += 1

function(arr + start_pos)

现在,数组已满。

现在只需要将最后一个元素复制到数组的开头(在 start_pos 到结尾之后)并将 working_pos 设置回 0 取决于额外元素的数量,这需要每 10 次、100 次甚至 1000 次迭代执行一次!

复制的结果是:

arr == [6, 7, 8, 9, 10, 11, 9, 10, 11]
                            *
start_pos = -1 // prepare for the +1 in regular iteration.

下一个附加值 (12) 将覆盖 * 值

arr == [6, 7, 8, 9, 10, 11, 12, 10, 11]

start_pos += 1 // is 0 now

function(arr + start_pos)

当然,您需要一个变量来确定 pos 以在另一个 val 后面插入新元素,或者您从 start_pos + nElemsToProcess 派生

如果你的 function() 只使用标准容器,那么它可能不是满足速度需求的正确选择。

【讨论】:

  • 谢谢!看到其他观点真的很有趣 :) 但是使用这种方法,我们仍然必须在某些时候复制,对吗?与不需要复制的循环缓冲区相比,您知道什么时候值得吗?顺便说一句,这就是你所说的极端副本? (以前从未听说过)
  • 我的意思是,与将所有内容复制到新数组相比,成本大大降低,因为您可以直接访问一行中的所有元素无需环绕需要带圆形)。问题是,Tensor 如何获取数据(总是复制!?)。
  • 看来是这样:/ 到目前为止,我还没有找到一种不同的方法。我会先尝试你的第一个方法我将复制张量中每个元素的元素。
  • 你只是填写一系列数字吗?张量代码在 git hub 上,TensorBuffer 似乎允许直接访问内存。但是要了解它的使用方式以及如何正确访问需要深入研究。 github.com/tensorflow/tensorflow/blob/master/tensorflow/core/…
  • 好的,我会看看。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 2014-11-16
  • 2015-04-08
  • 2012-12-22
  • 1970-01-01
相关资源
最近更新 更多