微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何避免使用临时字节数组将size_t数组的16个元素的最后7位加载到__m128i中?

如何解决如何避免使用临时字节数组将size_t数组的16个元素的最后7位加载到__m128i中?

对于我的哈希图实现,我要在长度为NBUCKETS的数组中为每个地图元素缓存哈希,其中每个元素都对应于哈希图中的一个元素。假设哈希由64位组成,则前57位决定哈希图中的位置(存储桶),而后7位(即H2(hash))用作控制表的控制字节。更具体地说,在使用线性探测在地图中查找元素时,H2(hash)在比较实际键之前,先使用SIMD内部函数对16个元素进行比较。因此,每次对probe_group()调用都会同时探测地图的16个元素。

但是用group中的16个元素填充hash_arr数组是昂贵的。我想避免使用临时group数组,而是将hash_arr中16个连续哈希值的最后7位直接加载到__m128i(即ctrl)中。>

是否有一种方法可以将hash_arr中16个哈希值的最后7位直接加载到__m128i中,而不是使用临时字节数组group

#include <immintrin.h>
#include <stdint.h>
#include <stdio.h>

#define NBUCKETS 100
#define GROUP_SIZE 16

typedef char h2_t;

// return the lowest byte 
static inline h2_t H2(size_t hash)
{
    return hash & 0x7f;
}

// If ith element in `group` is 'hash',then ith bit in `match` will be 1,// otherwise it will be 0
static inline uint16_t probe_group(h2_t hash,h2_t *group)
{

    __m128i ctrl  = _mm_loadu_si128((__m128i*) group);
    __m128i match = _mm_set1_epi8(hash);
    return _mm_movemask_epi8(_mm_cmpeq_epi8(match,ctrl));
}

int main()
{
    size_t hash_arr[NBUCKETS];
    for (int i = 0; i < NBUCKETS; i++)
        hash_arr[i] = i;

    // Todo Optimize this: Avoid using this array. Instead load the last 7 bits of 16 hash values directly into a `__m128i`.
    const int start_pos = 90;
    h2_t group[GROUP_SIZE];
    for (int i = 0; i < GROUP_SIZE; i++)
        group[i] = H2(hash_arr[(start_pos + i) % NBUCKETS]);

    // Element to be searched for in `group`.  ASCII for 'c' is 99
    h2_t find_ele = 'c';

    uint16_t match = probe_group(find_ele,group);

    for (int i = 0; i < GROUP_SIZE; i++) {
        if ((match >> i) & 1U)
            printf("Element at index %d in group is equal to %c\n",i,find_ele);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。