迭代任意内存和可能的对齐问题

时间:2018-03-20 17:19:12

标签: c hash memory-alignment strict-aliasing

我在C中实现了一个简单的哈希映射,因此我实现了一个通用且简单的哈希函数,该函数具有以下实现:

static inline int64_t hash(void_t *key, size_t ksize)
{
    int64_t hash = 0;
    char_t *key_str = key;

    for (size_t i = 0; i < ksize; i++)
    {
        char_t c = key_str[i];
        hash = 31 * hash + c;
    }

    return hash;
}

我想知道它是否更好地实现它:

static inline int64_t hash_x64(void_t *key, size_t ksize)
{
    int64_t hash = 0;

    size_t remain_ksize = ksize;
    size_t i = 0;

    while (remain_ksize >= sizeof(int64_t)) 
    {
        int64_t *val = key + i;
        hash = 31 * hash + *val;

        remain_ksize -= sizeof(int64_t);
        i += sizeof(int64_t);
    }

    char_t *key_str = key;

    for (; i < remain_ksize; i++)
    {
        char_t c = key_str[i];
        hash = 31 * hash + c;
    }

    return hash;
}

这是否违反任何对齐/别名规则?这个代码在x64架构上是否安全?它会在x64上执行得更快,还是编译器已经优化了底层架构的哈希函数?

1 个答案:

答案 0 :(得分:1)

无法保证传入的缓冲区在64位边界上正确对齐。因此,后一代码由于未对齐的内存评估而面临崩溃的风险。根据传入的内容,可能还存在严格的别名问题。

您最好一次读取一个字节。它避免了这两个问题,并且性能上的任何差异都可能是微不足道的。