在D语言中比较两块内存的最有效方法是什么?

dsi*_*cha 7 algorithm performance d binary-search low-level

我需要一个内存块的比较函数,用于对D编程语言中的字节数组进行二进制搜索.它不需要任何有用的语义.它只需要很快并且是一个有效的比较函数(产生总排序的函数).已知要比较的存储器块具有相同的长度.

C memcmp实际上非常慢,因为它试图保留有用的字符串比较语义,这是我不需要的.以下是迄今为止我提出的最佳方法.有没有人知道更好的事情,最好不要使用非便携式CPU特定指令?

// Faster than C's memcmp because it doesn't preserve any meaningful
// semantics.  It's just a completely arbitrary, but really fast,
// comparison function.
int memoryCompare(const(void)* lhs, const(void)* rhs, size_t n) {
    for(; n >= uint.sizeof; n -= uint.sizeof) {
        if( *(cast(uint*) lhs) < *(cast(uint*) rhs)) {
            return -1;
        } else if( *(cast(uint*) lhs) > *(cast(uint*) rhs)) {
            return 1;
        }
        lhs += uint.sizeof;
        rhs += uint.sizeof;
    }

    for(; n >= ubyte.sizeof; n -= ubyte.sizeof) {
        if( *(cast(ubyte*) lhs) < *(cast(ubyte*) rhs)) {
            return -1;
        } else if( *(cast(ubyte*) lhs) > *(cast(ubyte*) rhs)) {
            return 1;
        }
        lhs += ubyte.sizeof;
        rhs += ubyte.sizeof;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编辑:我已阅读SSE,我不想使用它有三个原因:

  1. 它不便携.
  2. 它需要在ASM中编程.
  3. 比较指令假设您的数据是浮点数,如果某些数据恰好与NaN的模式匹配,则可能会出现问题.

rsp*_*rsp 3

你可以尝试:

  • 检查 uint 是否是适合您的目标 CPU 的最大类型(ulongs 可能更适合本机寄存器)
  • 使用 2 个该类型的指针
  • 使用 *p++ 使用 2 个局部变量(不要为 1 个值取消引用指针 2 次)
  • 预先除掉第一个循环的计数器(使用 while (counter--))
  • 通过用开关替换它来展开第二个循环(如果 sizeof(适合寄存器的类型)已知并且将始终相同。)

编辑:如果第一个循环是瓶颈,则展开可能是答案。结合在值相等的情况下将条件数量减半,展开 4 次,我得到如下结果:

uint* lp = (uint*)lhs;
uint* rp = (uint*)rhs;
uint  l;
uint  r;
int count = (n / uint.sizeof) / 4;

while (count--) {
    if( (l = *lp++) != (r = *rp++) {
        return (l < r) ? -1 : 1;
    }
    if( (l = *lp++) != (r = *rp++) {
        return (l < r) ? -1 : 1;
    }
    if( (l = *lp++) != (r = *rp++) {
        return (l < r) ? -1 : 1;
    }
    if( (l = *lp++) != (r = *rp++) {
        return (l < r) ? -1 : 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,这留下了(n / uint.sizeof) % 4迭代要做,你可以通过交错一个开关将其混合到这个循环中,我把它留给读者邪恶的笑容作为练习。