首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SSE4内存与不同位置的比较

SSE4内存与不同位置的比较
EN

Stack Overflow用户
提问于 2017-09-04 05:24:19
回答 1查看 97关注 0票数 1

当我试图用SSE4优化以下内容时,我自己的实现让我吃了一惊:

代码语言:javascript
复制
std::distance(byteptr, std::mismatch(byteptr, ptr + lenght, dataptr).first)

这会比较byteptr和data,并返回字节不匹配的索引。我真的需要原始速度,因为我正在处理如此多的内存,以至于RAM的速度已经是一个瓶颈。使用SSE4一次获取和比较16个字节将提供速度提升,因为一次比较16个字节会更快。

这是我当前无法使用的代码。使用的是GCC SSE内部函数,需要SSE4.2:

代码语言:javascript
复制
// define SIMD 128-bit type of bytes.
typedef char v128i __attribute__ ((vector_size(16)));
// mask of four low bits set.
const uintptr_t aligned_16_imask = (uintptr_t)15;
// mask of four low bits unset.
const uintptr_t aligned_16_mask = ~aligned_16_imask;

inline unsigned int cmp_16b_sse4(v128i *a, v128i *b) {
    return __builtin_ia32_pcmpistri128(__builtin_ia32_lddqu((char*)a), *b, 0x18);  
}

size_t memcmp_pos(const char * ptr1, const char * ptr2, size_t lenght)
{
    size_t nro = 0;
    size_t cmpsz;
    size_t alignlen = lenght & aligned_16_mask;
    // process 16-bytes at time.
    while(nro < alignlen) {
        cmpsz = cmp_16b_sse4((v128i*)ptr1, (v128i*)ptr2);
        ptr1 += cmpsz;
        ptr2 += cmpsz;
        nro += cmpsz;
        // if compare failed return now.
        if(cmpsz < 16)
            return nro;
        if(cmpsz != 16)
            break;
    }
    // process remainder 15 bytes:
    while( *ptr1 == *ptr2 && nro < lenght) {
        ++nro;
        ++ptr1;
        ++ptr2;
    }
    return nro;
}

在测试上面的函数时,它在大多数情况下都可以工作,但在某些情况下会失败。

EN

回答 1

Stack Overflow用户

发布于 2017-09-04 08:44:31

pcmpistri的一个已知问题是,它总是读取完整的16个字节-甚至超出变量的末尾。这在页面边界上,在分配给未分配内存的边界上成为一个问题。参见here (scroll down to "Renat Saifutdinov")

即使支持未对齐的读取,也可以通过仅使用源的对齐读取来避免这种情况,see this SO answer

这可能是代码失败的原因之一。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46027952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档