数组反向 - 比使用临时对象切换要慢

Joh*_*0te 1 c++ algorithm xor

我正在阅读一个关于反转数组的最快方法的问题(最终不那么令人兴奋),我在链接处看到了一个有趣的评论:

/sf/answers/79031991/

引用的解决方案显示了这两种可能性

//Possibility #1
void reverse(char word[])
{
    int len=strlen(word);
    char temp;
    for (int i=0;i<len/2;i++)
    {
            temp=word[i];
            word[i]=word[len-i-1];
            word[len-i-1]=temp;
    }
}

//Possibility #2
void reverse(char word[])
{
    int len=strlen(word);
    for (int i=0;i<len/2;i++)
    {
        word[i]^=word[len-i-1];
        word[len-i-1]^=word[i];
        word[i]^=word[len-i-1];
    }
}
Run Code Online (Sandbox Code Playgroud)

并且评论指出:"使用XOR比使用临时对象进行交换慢得多."

没有人对此提出质疑.所以,我的问题是:

  1. 这是真的?
  2. 为什么这是真的?
  3. 如果这是一个非内置类型的阵列,它仍然是真的吗?

dth*_*rpe 5

xor循环包含2个内存读取和每行1个内存写入,每次循环迭代总共6次读取和3次写入.此外,写入word [i]的第一行与从word [i]读取的下一行之间存在强烈的依赖关系.这将阻止流水线操作,或者如果两条线并行执行,则从word [i]读取的第二行将停止,直到第一行的写入完成.第二行和第三行之间存在另一种这样的依赖关系.

在temp var循环中,temp var几乎肯定会存储在CPU寄存器中,而不是存储在主存储器中.因此,temp var循环的总内存I/O数是2次读取和2次写入.语句之间存在松散的数据流依赖关系,但它们是可在流水线前读取的.xor示例中的数据流依赖性是写后读取的,如果不拖延管道,这将更加困难.

与2次读取+ 2次写入相比,6次读取+ 3次写入.2 + 2具有明显的优势.