在C中合并字节数组的最有效方法是什么?

时间:2011-02-07 12:47:50

标签: c arrays

假设我有两个char数组,每个位置都是1或0。 这两个数组在不同的进程中计算,然后发送回主服务器进行组合,因此每个数组只写入其数组的某个范围:

p1:[0,0,0,0,1,1,0,1]

p2:[1,0,1,1,0,0,0,0]

目标:[1,0,1,1,1,1,0,1]

但是,这些可能是非常大的数组。除了循环其中一个之外,还有一种超快速的方法吗?

澄清一下,它们应该是OR'd。

4 个答案:

答案 0 :(得分:2)

假设字节粒度足够好,您可能希望使用memcpy将它们复制到输出数组中:

memcpy(goal, p2, 4);
memcpy(goal + 4, p1 + 4, 4);

您可以通过让p1p2仅包含自己的范围来进一步优化这一点,例如:

char p1[4] = { 1, 1, 0, 1 };
char p2[4] = { 1, 0, 1, 1 };
char goal[8];
memcpy(goal, p2, 4);
memcpy(goal + 4, p1, 4);

请注意,您可能还需要查看位向量打包 - 在此处将8位打包到每个char中。这将为大型阵列节省大量内存,但这会使访问变得复杂。

答案 1 :(得分:0)

我建议:

  1. 分析以确保这确实是一个瓶颈。
  2. 研究这种“矢量风格”,即通过对齐字节数组,然后使用常规线性循环,使用单机操作尽可能多地处理字节,可能通过访问unsigned long long
  3. 重新排列,以便子进程以更有效的格式处理报告,可能使用某种运行长度压缩。

答案 2 :(得分:0)

如果您正在使用不同的处理器也许您应该考虑使用MPI库进行缩减操作,它非常快

MPI_Reduce(p, goal, size, MPI_CHAR, MPI_LOR, goal_process_id, MPI_COMM_WORLD);

如果您使用不同的线程,那么OpenMP在代码简单性方面也很出色(这是快速而脏的代码):

#pragma omp parallel for reduction(|, out)
for(int i=0; i<size; i++)
  out[i] = p1[i] * p2[i];

答案 3 :(得分:0)

为什么使用数组?因为在速度和内存消耗方面最有效的方法无疑是在字节级别上实际工作。而不是不必要地来回抛掷数组。

也许是这样的?

uint8 proc_n (void)
{
  uint8 result = 0x00;
  uint8 i;

  for(i=0; i<8; i++)
  {
    if(something)
    {
      result |= (0x01 << i);
    }
  }

  return result;
}



typedef uint8 (*Proc_ptr)(void);

Proc_ptr proc_array [PROCESSES] =
{
  proc_1,
  proc_2,
  ...
};

uint8 result = 0x00;

for(i=0; i<PROCESSES; i++)
{
  result |= proc_array[i]();
}