SSE4内存与差异位置比较

Posted

技术标签:

【中文标题】SSE4内存与差异位置比较【英文标题】:SSE4 memory compare with difference position 【发布时间】:2017-09-03 21:24:18 【问题描述】:

我自己的实现在尝试使用 SSE4 优化跟随时让我反感:

std::distance(byteptr, std::mismatch(byteptr, ptr + lenght, dataptr).first)

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

这是我当前无法工作的代码。 它使用 GCC SSE 内在函数并需要 SSE4.2:

// 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;

在测试上述功能时,它大部分时间都可以工作,但在某些情况下会失败。

【问题讨论】:

“失败”是什么意思?崩溃、误报/误报...? 上述 SSE 代码产生的结果与基于 std::mismatch 的结果不同。 我发现我做错了什么:代码应该使用pcmpestri,因为pcmpistri实际上试图处理空字节。我的输入数据本质上是非结构化位,所以这破坏了代码。 【参考方案1】:

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

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

这可能是您的代码失败的可能性之一。

【讨论】:

我认为代码不会遇到这些问题。对于每轮循环 16 字节,我有 lenght &amp; aligned_16_mask 它将第一个循环中要处理的字节数舍入为 16 的倍数。

以上是关于SSE4内存与差异位置比较的主要内容,如果未能解决你的问题,请参考以下文章

GPS定位 为啥与实际位置有差异?怎么调整?

_mm_cmpistrm SSE4.2 固有模式

查找行之间的绝对差异并将差异与其他行进行比较

Java(C#)基础差异-字符串

与 Visual Studio 2017 中的架构比较的意外差异

比较与特定字段有关的两个表之间的差异时如何正确连接