C++ 算术模板交换比std::Swap更快?

C++ 算术模板交换比std::Swap更快?,c++,optimization,C++,Optimization,我环顾四周,将一个基本的临时变量交换与一个仅限于算术类型的类型模板结合起来。为什么这比std::swap更快 下面是我用于测试的具体实现:尝试清除缓存以测试一致性,请参阅 结果:比例为5:1 std::swap -> 5086 <T> swp -> 1397 当启用了优化时,看看这个简单代码的汇编-O2 包括 当对每个编译器进行比较时,foo和bar的机器代码是完全相同的 更重要的是,msvc能够对循环进行优化,检测到它们不会像规则一样引入任何可见的结果 因此,由于

我环顾四周,将一个基本的临时变量交换与一个仅限于算术类型的类型模板结合起来。为什么这比std::swap更快

下面是我用于测试的具体实现:尝试清除缓存以测试一致性,请参阅

结果:比例为5:1

std::swap -> 5086
<T> swp   -> 1397

当启用了优化时,看看这个简单代码的汇编-O2

包括

当对每个编译器进行比较时,foo和bar的机器代码是完全相同的

更重要的是,msvc能够对循环进行优化,检测到它们不会像规则一样引入任何可见的结果

因此,由于结果不同,这意味着测试不正确

请记住,从技术角度来看,测试诸如swap这样的小而快的功能的性能是非常困难的,而且很容易出错,从而导致错误的结论


基本上,看起来您已经达到了std::clock的时间分辨率极限。

当启用优化时,看看这个简单代码的汇编-O2

包括

当对每个编译器进行比较时,foo和bar的机器代码是完全相同的

更重要的是,msvc能够对循环进行优化,检测到它们不会像规则一样引入任何可见的结果

因此,由于结果不同,这意味着测试不正确

请记住,从技术角度来看,测试诸如swap这样的小而快的功能的性能是非常困难的,而且很容易出错,从而导致错误的结论


基本上,看起来您已经达到了std::clock的时间分辨率限制。

请用完整代码、编译器设置和性能度量显示a编译器可能正在优化您的算术交换,而没有实际使用临时变量。人们希望一个像样的std::swap实现已经针对算术类型进行了优化。你说的更快是什么意思?你设计了什么实验。你是如何测量运行时间的?哪种编译器,优化,架构?@DanielLangr x64,VS编译器,标准优化。我不理解你的实验。您分配了一个大数组,但随后测量了两个局部变量的交换。这两个循环最终都没有效果,编译器可能会对其进行完全优化。此外,还有优化:。此外,减去std::clock的结果不会得到毫秒。请在完整代码、编译器设置和性能度量中显示a。编译器可能正在优化算术交换,而没有实际使用临时变量。人们希望一个像样的std::swap实现已经针对算术类型进行了优化。你说的更快是什么意思?你设计了什么实验。你是如何测量运行时间的?哪种编译器,优化,架构?@DanielLangr x64,VS编译器,标准优化。我不理解你的实验。您分配了一个大数组,但随后测量了两个局部变量的交换。这两个循环最终都没有效果,编译器可能会对其进行完全优化。此外,还有优化:。此外,减去std::clock的结果不会得到毫秒,如果我包含for循环来调整x,y变量,那么编译器就无法优化它。对吗?在这种情况下,编译器无论如何都不能真正优化for循环?由于每个循环的值都被交换,编译器不应该做任何事情。@FatalSleep在循环之后,交换的变量的值与循环之前相同。是的,编译器可以完全优化循环。我建议在进行此类实验之前,了解更多关于优化和“仿佛”规则的信息。请提供详细信息:编译器、如何构建它以及如何运行它。@MarekR相当基本,VS2019中的默认控制台应用程序设置。没有改变任何东西。如果我包含for循环来调整x,y变量,那么编译器就无法优化它。对吗?在这种情况下,编译器无论如何都不能真正优化for循环?由于每个循环的值都被交换,编译器不应该做任何事情。@FatalSleep在循环之后,交换的变量的值与循环之前相同。是的,编译器可以完全优化循环。我建议在进行此类实验之前,了解更多关于优化和“仿佛”规则的信息。请提供详细信息:编译器、如何构建它以及如何运行它。@MarekR相当基本,VS2019中的默认控制台应用程序设置。什么都没变。
int main() {
    const size_t bigger_than_cachesize = 10 * 1024 * 1024;
    long* p = new long[bigger_than_cachesize];
    for (int i = 0; i < bigger_than_cachesize; i++) p[i] = rand();
    std::cout << "Cache is flushed..." << std::endl;
    /// IGNORE ABOVE (ATTEMPTING TO CLEAR CACHE FOR CONSISTENCY)

    double duration;
    int x = 2560, y = 435;
    std::clock_t start;
    start = std::clock();

    for(int i = 0; i < 100000000; i++) std::swap(x,y);

    duration = (std::clock() - start);
    std::cout << "std::swap: " << duration << '\n';
    duration = 0;
    start = std::clock();

    for (int i = 0; i < 100000000; i++) swp(x,y);

    duration = (std::clock() - start);
    std::cout << "swapTMP: " << duration << '\n';
}
std::swap -> 5086
<T> swp   -> 1397