代码之家  ›  专栏  ›  技术社区  ›  alvatar

在C数组中进行位操作的最有效方法是什么

  •  10
  • alvatar  · 技术社区  · 16 年前

    char byte_array[10];
    

    char byte_mask[10];
    

    我想对每个字节进行位操作,得到另一个数组,即第一个数组加上第二个数组的结果。

    最有效的方法是什么?

    谢谢你的回答。

    3 回复  |  直到 16 年前
        1
  •  15
  •   Jason Cohen    16 年前
    for ( i = 10 ; i-- > 0 ; )
        result_array[i] = byte_array[i] & byte_mask[i];
    
    • 向后移动会预加载处理器缓存行。
    • 在比较中包含减量可以节省一些指令。

    这将适用于所有阵列和处理器。然而,如果你知道你的数组是单词对齐的,一种更快的方法是转换为更大的类型并进行相同的计算。

    n=16 而不是 n=10

    uint32_t* input32 = (uint32_t*)byte_array;
    uint32_t* mask32 = (uint32_t*)byte_mask;
    uint32_t* result32 = (uint32_t*)result_array;
    for ( i = 4 ; i-- > 0 ; )
        result32[i] = input32[i] & mask32[i];
    

    uint32_t n

        2
  •  5
  •   Antti Huima    16 年前

    如果你想让它更快,请确保byte_array的长度是4的倍数(在64位机器上为8),然后:

    char byte_array[12];
    char byte_mask[12];
    /* Checks for proper alignment */
    assert(((unsigned int)(void *)byte_array) & 3 == 0);
    assert(((unsigned int)(void *)byte_mask) & 3 == 0);
    for (i = 0; i < (10+3)/4; i++) {
      ((unsigned int *)(byte_array))[i] &= ((unsigned int *)(byte_mask))[i];
    }
    

    这比逐字节执行要快得多。

        3
  •  1
  •   Scriptable    10 年前
    \#define CHAR_ARRAY_SIZE    (10)
    \#define INT_ARRAY_SIZE     ((CHAR_ARRAY_SIZE/ (sizeof (unsigned int)) + 1)
    
    typedef union _arr_tag_ {
    
        char          byte_array [CHAR_ARRAY_SIZE];
        unsigned int  int_array [INT_ARRAY_SIZE]; 
    
    } arr_tag;
    

    arr_tag arr_src, arr_result, arr_mask;
    
    for (int i = 0; i < INT_ARRAY_SIZE; i ++) {
        arr_result.int_array [i] = arr_src.int_array[i] & arr_mask.int_array [i];
    }