算法:取出数组的每第4项

时间:2014-02-11 14:06:11

标签: c++ c arrays algorithm real-time

我有两个巨大的数组(int source [1000],dest [1000]在下面的代码中,但实际上有数百万个元素)。源数组包含一系列int,其中我想要每4个中复制3个。

例如,如果源数组是:

int source[1000] = {1,2,3,4,5,6,7,8....};
int dest[1000];

这是我的代码:

for (int count_small = 0, count_large = 0; count_large < 1000; count_small += 3, count_large +=4)
    {
      dest[count_small] = source[count_large];
      dest[count_small+1] = source[count_large+1];
      dest[count_small+2] = source[count_large+2];
    }

最后,dest控制台输出将是:

1 2 3 5 6 7 9 10 11...

但是这个算法太慢了!是否有可以使用/包含的算法或开源函数?

谢谢:)

编辑:我的阵列的实际长度约为1百万(640 * 480 * 3)

编辑2:处理此for循环大约需要0.98秒到2.28秒,而其他代码只需要0.08秒到0.14秒,因此设备仅为循环使用至少90%的cpu时间

5 个答案:

答案 0 :(得分:3)

您可以尝试memcpy而不是单独的作业:

memcpy(&dest[count_small], &source[count_large], sizeof(int) * 3);

答案 1 :(得分:3)

嗯,渐近的复杂性就像它会得到的一样好。通过将值加载为四个4路SIMD整数,将它们混合为三个4路SIMD整数并将它们写回来,你可能可以获得更好的性能,但即使这样也不会非常快。

尽管如此,处理1000个元素(编辑:或一百万个元素)的时间将完全是微不足道的。如果您认为这是程序中的瓶颈,那么您就错了。

答案 2 :(得分:3)

在您做更多事情之前,请尝试分析您的应用程序,并确定这是否是最适合花时间的地方。然后,如果这是一个热点,确定它的速度有多快,以及您需要多快的速度?然后测试替代品;线程或OpenMP的开销甚至可能会降低它的速度(尤其如你所知,如果你使用的是单核处理器 - 在这种情况下它根本无法帮助)。对于单线程,我会按照肖恩的回答来查看memcpy

@Sneftel还在下面引用了other options SIMD integers

一种选择是尝试并行处理循环,看看是否有帮助。您可以尝试使用OpenMP标准(请参阅Wikipedia link here),但您必须根据具体情况进行尝试,看看它是否有帮助。我最近在AI实现中使用了它,它帮助了我们很多。

#pragma omp parallel for
for (...)
{
   ... do work
}

除此之外,您仅限于编译器自己的优化。

您还可以查看C11中最近的线程支持,不过您可能最好使用预先实现的框架工具,例如parallel_for(在Visual Studio的new Windows Concurrency Runtime through the PPL中可用,如果这就是你的话“正在使用”而非滚动自己。

parallel_for(0, max_iterations,
    [...] (int i)
    {
        ... do stuff
    }
);

for循环内,您还有其他选项。您可以尝试迭代并跳过每个for的for循环,而不是每次迭代执行3次复制(仅在(i+1) % 4 == 0时跳过),或者按{{3}对3个整数的组执行块memcopy运算}}。对于其中一些,您可能会实现稍微不同的编译器优化,但不太可能(memcpy可能与您获得的速度一样快。)

for (int i = 0, int j = 0; i < 1000; i++)
{
  if ((i+1) % 4 != 0)
  { 
    dest[j] = source[i];
    j++;
  }
}

然后您应该开发一个测试装备,以便您可以快速进行性能测试并为您决定最佳测试。最重要的是,在优化其他地方之前,决定花多少时间花在这上面。

答案 3 :(得分:0)

你的阵列大小只有1000吗?如果是这样,它怎么慢?应该马上完成! 只要您创建一个新数组并为单线程应用程序,这是唯一的AFAIK。

但是,如果数据集很大,您可以尝试使用多线程应用程序。

此外,你可以探索一个更大的数据类型保存值,以便数组大小减少......这是否适用于您的实际应用程序。

答案 4 :(得分:0)

如果你有Nvidia卡,你可以考虑使用CUDA。如果不是这种情况,您也可以尝试其他并行编程方法/环境。