C语言高效数组掩码

时间:2011-08-16 22:47:11

标签: c arrays

我有两个BOOL的3维数组,我想在它们之间进行掩码。 我的意思是创建第三个数组:third[i][j][k] = first[i][j][k] && second[i][j][k],每个i,j,k。

  1. 我使用c语言(可以是汇编)
  2. 我需要屏蔽操作尽可能快
  3. 可以假设第一个和第二个具有相同的大小。
  4. 如果它可以提高性能,我可以将数据从数组重新排列到其他数据排列。
  5. 已编辑:每个数组维度为100

    谢谢!

3 个答案:

答案 0 :(得分:3)

我在评论中提到了这一点,但这里有一些工作代码(希望如此。我没有对此进行测试,也没有通过编译器提供它。这只是为了这个想法)。如果您有一个100x100x100阵列,您尝试建模为位掩码,那么您可以执行以下操作:

// Create two bitmasks
const unsigned int BITS_PER_BYTE = 8;
const unsigned int DIM = 100;
const unsigned int BITS_PER_VALUE = BITS_PER_BYTE * sizeof(unsigned long);
const unsigned long MASK_SIZE = (DIM * DIM * DIM) / BITS_PER_VALUE;
unsigned long bitmask1[MASK_SIZE] = {0};
unsigned long bitmask2[MASK_SIZE] = {0};
unsigned long bitmask_result[MASK_SIZE];

// Set the two bitmasks, this is probably sub-optimal but you
// mention that setting bitmasks isn't supposed to be overly performant

// set bitmask1 (repeat something similar for bitmask2)
for (int i = 0; i < DIM; ++i)
  for (int j = 0; j < DIM; ++j)
    for (int k = 0; k < DIM; ++k) {
      // set bitmask[i][j][k] to 1
      unsigned int offset = DIM*DIM*i + DIM*j + k;
      unsigned int long_offset = offset / BITS_PER_VALUE;
      unsigned int bit_offset  = offset % BITS_PER_VALUE;
      // XXX SET THIS TO WHATEVER VALUE YOU HAVE, 1 FOR true and 0
      // FOR false. I'M SETTING EVERYTHING TO TRUE FOR THE SAKE OF
      // EXAMPLE
      bitmask1[long_offset] = 1 << bit_offset;
    }

// Now to actually compare:
for (int i = 0; i < MASK_SIZE; ++i) {
  bitmask_result[i] = bitmask1[i] & bitmask2[i];

// and that's it. bitmask_result will now have your answers. decompose
// the bitmask by doing the reverse of the above set loop

答案 1 :(得分:2)

您知道,将数据安排在内存中以便所有计算都可以在一个(非常优化的,SSE等)循环中完成,这将有所帮助。但是,考虑到您正在访问大量内存执行非常非常快速的操作,因此优化不会太多。并且,如果你选择重新安排内存,安排过程可能比计算本身慢。

看着这个问题,我想到了查尔斯·佩佐尔德在“美丽的代码”一书中写的一篇文章。您可以为循环的每一行的每个值生成代码模式(100种不同的代码模式),只有在相应的位值为1时才生成赋值,然后根据该行的位值“junp”到正确的实现你正在处理。您需要为不同的掩码使用位域。您将3嵌套循环转换为2嵌套循环,并为内循环优化代码(不是太糟糕),必须使用其他实用程序(或简单的C / C ++)生成代码本身内循环的不同值。您应该阅读本章以了解它。真的很整洁。

答案 2 :(得分:1)

我会说只有性能分析会回答你的问题,而且我不会那样做,但是我会简单地使用for循环,只是在没有执行的情况下才会真正看得更远。

不要过早优化。