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

时间:2012-02-24 02:35:07

标签: c++ algorithm xor

我正在阅读一个关于反转阵列的最快方法的问题(结果不那么令人兴奋),我在链接处发现了一个有趣的评论:

https://stackoverflow.com/a/1129028/857994

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

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

并且评论指出:“使用XOR将比使用临时对象进行交换慢得多。”

没有人对此提出异议。所以,我的问题是:

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

1 个答案:

答案 0 :(得分:5)

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

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

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