我有两个数组。一个是第二个大小的“x”因子。
我需要从第一个(较大的)数组复制到第二个(较小的)数组只复制其x元素。 含义0,x,2x。
每个数组都作为块存储在内存中。 该数组具有简单的值。 我目前正在使用循环。
有更聪明的方法吗?
也许是ostream
?
谢谢!
答案 0 :(得分:2)
你正在做这样的事吗?
#include <cstddef>
int main()
{
const std::size_t N = 20;
const std::size_t x = 5;
int input[N*x];
int output[N];
for(std::size_t i = 0; i < N; ++i)
output[i] = input[i*x];
}
好吧,我不知道任何能做到这一点的函数,所以我会使用for循环。这很快。
编辑:更快的解决方案(避免乘法)(C ++ 03版本)
int* inputit = input;
int* outputit = output;
int* outputend = output+N;
while(outputit != outputend)
{
*outputit = *inputit;
++outputit;
inputit+=x;
}
答案 1 :(得分:1)
copy_if(a.begin(), a.end(), b.end(), [&] (const int& i) -> bool
{ size_t index = &i - &a[0]; return index % x == 0; });
测试案例将是:
#include <iostream>
#include <vector>
#include <algorithm> // std::copy_if
using namespace std;
int main()
{
std::vector<int> a;
a.push_back(0);
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(4);
std::vector<int> b(3);
int x = 2;
std::copy_if(a.begin(), a.end(), b.begin(), [&] (const int& i) -> bool
{ size_t index = &i - &a[0]; return index % x == 0; });
for(int i=0; i<b.size(); i++)
{
std::cout<<" "<<b[i];
}
return 0;
}
请注意,您需要使用兼容C ++ 11的编译器(如果是gcc,使用-std = c ++ 11选项)。
答案 2 :(得分:1)
如果我说得对,你想要复制每个第n个元素。最简单的解决方案是
#include <iostream>
int main(int argc, char **argv) {
const int size[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int out[5];
int *pout = out;
for (const int *i = &size[0]; i < &size[10]; i += 3) {
std::cout << *i << ", ";
*pout++ = *i;
if (pout > &out[4]) {
break;
}
}
std::cout << "\n";
for (const int *i = out; i < pout; i++) {
std::cout << *i << ", ";
}
std::cout << std::endl;
}
答案 3 :(得分:1)
template<typename InIt, typename OutIt>
void copy_step_x(InIt first, InIt last, OutIt result, int x)
{
for(auto it = first; it != last; std::advance(it, x))
*result++ = *it;
}
int main()
{
std::array<int, 64> ar0;
std::array<int, 32> ar1;
copy_step_x(std::begin(ar0), std::end(ar0), std::begin(ar1), ar0.size() / ar1.size());
}
答案 4 :(得分:0)
这样做的正确和干净的方式就像之前所说的一样。这里有很多好的答案告诉你如何做到这一点。
我不建议以下列方式进行,它取决于很多具体的东西,X的值范围,变量的大小和值范围等等,但对于某些人来说,你可以这样做:
for every 4 bytes:
tmp = copy a 32 bit variable from the array, this now contains the 4 new values
real_tmp = bitmask tmp to get the right variable of those 4
add it to the list
这只适用于你想要的值&lt; = 255和X == 4,但是如果你想要一个比循环更快的东西,这是一种方法。这可以修改为16位,32位或64位值和每2,3,4,5,6,7,8(64位)值,但对于X> 8,此方法将不起作用,或者对于未分配的值线性时尚。它也不适用于课程。
对于这种优化值得麻烦的代码需要经常运行 ,我假设您已经运行了一个分析器来确认旧副本是一个瓶颈,然后再开始实现类似这样的东西
答案 5 :(得分:0)
以下是对大多数CPU设计在这类事情上缺乏想象力的观察。
在某些OpenVPX上,您可以将数据从一个处理器DMA到另一个处理器。我使用的那个有一个非常先进的DMA控制器,它可以为你做这种事情。
例如,我可以要求它将你的大数组复制到另一个CPU,但跳过数组的N个元素,就像你想要做的那样。好像通过魔术一样,目标CPU将在其内存中具有较小的阵列。如果我想要执行矩阵变换等,我也可以。
好处是它完全没有CPU时间;这一切都是由DMA引擎完成的。然后,我的CPU可以集中精力处理更难的数据,而不是将数据混乱。
我认为PS3中的Cell处理器可以在内部执行此类操作(我知道它可以绕DMA数据,我不知道它是否会同时进行条带挖掘)。一些DSP芯片也可以做到。但是x86没有这样做,这意味着我们的软件程序员必须编写荒谬的循环,只是以简单的模式移动数据。打哈欠。
我过去编写了一个多线程memcpy()来做这种事情。你打败for循环的唯一方法是让几个线程在几个并行的块中进行for循环。
如果选择正确的编译器(例如Intel的ICC或Sun / Oracles Sun Studio),可以代表您自动并行化for循环(因此您的源代码不会更改)。这可能是打败原始循环的最简单方法。