繁体   English   中英

为什么一个类中相同函数定义的执行时间慢于10倍以上?

[英]Why the execution time of same function definition within a class is slower more than 10x time?

不确定compiler执行哪种优化,但为什么在类中相同的函数定义比调用全局方法的速度慢?

#include <iostream>
#include <chrono>

#define MAX_BUFFER 256
const int whileLoops = 1024 * 1024 * 10;

void TracedFunction(int blockSize) {
    std::chrono::high_resolution_clock::time_point pStart;
    std::chrono::high_resolution_clock::time_point pEnd;

    double A[MAX_BUFFER];
    double B[MAX_BUFFER];
    double C[MAX_BUFFER];

    // fill A/B
    for (int sampleIndex = 0; sampleIndex < MAX_BUFFER; sampleIndex++) {
        A[sampleIndex] = sampleIndex;
        B[sampleIndex] = sampleIndex + 1000.0;
    }

    // same traced function
    pStart = std::chrono::high_resolution_clock::now();

    int whileCounter = 0;
    while (whileCounter < whileLoops) {
        for (int sampleIndex = 0; sampleIndex < blockSize; sampleIndex++) {
            double value = A[sampleIndex] + B[sampleIndex];

            C[sampleIndex] = value;
        }

        whileCounter++;
    }

    pEnd = std::chrono::high_resolution_clock::now();
    std::cout << "execution time: " << std::chrono::duration_cast<std::chrono::milliseconds>(pEnd - pStart).count() << " ms" << " | fake result: " << A[19] << " " << B[90] << " " << C[129] << std::endl;
}

class OptimizeProcess
{
public:
    std::chrono::high_resolution_clock::time_point pStart;
    std::chrono::high_resolution_clock::time_point pEnd;

    double A[MAX_BUFFER];
    double B[MAX_BUFFER];
    double C[MAX_BUFFER];

    OptimizeProcess() {
        // fill A/B
        for (int sampleIndex = 0; sampleIndex < MAX_BUFFER; sampleIndex++) {
            A[sampleIndex] = sampleIndex;
            B[sampleIndex] = sampleIndex + 1000.0;
        }
    }

    void TracedFunction(int blockSize) {
        // same traced function
        pStart = std::chrono::high_resolution_clock::now();

        int whileCounter = 0;
        while (whileCounter < whileLoops) {
            for (int sampleIndex = 0; sampleIndex < blockSize; sampleIndex++) {
                double value = A[sampleIndex] + B[sampleIndex];

                C[sampleIndex] = value;
            }

            whileCounter++;
        }

        pEnd = std::chrono::high_resolution_clock::now();
        std::cout << "execution time: " << std::chrono::duration_cast<std::chrono::milliseconds>(pEnd - pStart).count() << " ms" << " | fake result: " << A[19] << " " << B[90] << " " << C[129] << std::endl;
    }
};

int main() {
    int blockSize = MAX_BUFFER;

    // outside class
    TracedFunction(blockSize);

    // within class
    OptimizeProcess p1;
    p1.TracedFunction(blockSize);

    std::cout << std::endl;
    system("pause");

    return 0;
}

试过MSVC/Oi /Ot

~80ms vs 1200ms。 是否在compile-time使用blockSize作为常量进行循环展开?

不确定,因为我试图将blockSize随机设置为:

std::mt19937_64 gen{ std::random_device()() };
std::uniform_real_distribution<double> dis{ 0.0, 1.0 };

int blockSize = dis(gen) * 255 + 1;

结果相同......

如果使用GCC的最大优化标志(即O3进行编译,那么您将获得类似的执行时间。

在执行时间内执行函数或不执行函数的方面没有区别。


我看到的唯一区别是,您何时以及如何创建阵列。 在第一个函数中,数组是函数的自动变量。 在within函数中,数组是类的数据成员。

在某些情况下,这可以发挥作用。 使数组全局化(仅创建一次),您将看到执行时间没有差异(无论使用O1O2还是O3 )。


注意:使用O2编译,您将获得内部函数更快的执行时间(这与您提到的相反)。 准确地说是x1.35加速,正如您在Live Demo中看到的那样。

不过,请记住,当优化正确完成时,在这种情况下使用O3 ,您不应该看到任何重大差异!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM