gpt4 book ai didi

c++ - 当迭代器是类成员时,为什么在C++中for循环变慢

转载 作者:行者123 更新时间:2023-12-03 02:35:22 25 4
gpt4 key购买 nike

以前我自己曾问过这个问题,虽然不是很好。我已对此进行了改写和扩展,希望我澄清了两点。从初学者的 Angular 来看,这个问题非常多。

下面是一个简短的示例代码,该代码内联运行并作为函数的一部分运行。

代码将1加到数组的每个元素上,然后将每个元素除以2。目前这是任意的,只是占位符,可以处理更复杂但非常等效的内容。

作为背景,这会阻止实时应用程序的音频处理。这就是原因

int N = 44.1e3 * 60;

因此,从本质上讲,这将处理1分钟以44.1kHz采样的音频。

内联编写的显式代码比功能代码运行得快得多。尽管已经声明了计时器,但这并不是一个小小的区别,而是一个方法的问题,一个方法在1秒钟内运行,另一个方法在8秒钟左右(ymmv)。

函数调用将产生开销的罚款。可以通过更改优化标志来提高速度,但是没有什么办法可以使这两种方法都在相似的时间范围内运行。

我的问题是:
  • 是否可以更改函数调用方法,同时仍将其作为类保留在类中,以使其以与内联方法相似或完全相同的速度运行?
  • 是否可以使用任何编译器标志,这将导致两种方法在相似的时间范围内运行?如果是这样,它们将如何在Xcode中使用,最好是建议使用资源详细说明用法。

  • 下面的代码很简单,从风格上讲不是很专业。这是为了减少混乱,并希望将注意力集中在主要问题上。

    如果可以对类定义进行任何更改以适用于上述问题,我非常高兴。否则,我了解您的不满,但在这里可能与您无关。

    提供的时钟输出不是一个全面的基准测试工具。它包括两种方法之间较大的时差的基本说明。
    #include <iostream>
    #include <stdio.h>
    #include <sys/time.h>
    #include <math.h>

    class someClass {
    int n, i; // internal class loop indeces
    double foo[1000];
    int I = floor(sizeof(foo)/sizeof(foo[0])); // number of elements in foo
    public:
    void someFunction(int);
    };

    void someClass::someFunction(int N){
    for(n=N;n--; ){
    for(i=I;i--; ){
    foo[i]+= 1;
    foo[i]*= .5;
    }
    }
    }


    int main(){

    // this was initially an audio processing problem
    // Essentially, process a minute of audio

    int N = 44.1e3 * 60;


    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /// The Explicit Method
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    int n,i; // loop indeces
    double bar[1000];
    int I = floor(sizeof(bar)/sizeof(bar[0]));

    // START CLOCK
    std::clock_t start;
    double duration;
    start = std::clock();


    // Exactly what is defined in the function 'someFunction' above
    for(n=N;n--; ){
    for(i=I;i--; ){
    bar[i]+= 1;
    bar[i]*=.5;
    }
    }

    // END CLOCK
    duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
    std::cout<<"Explicit Method Time (seconds): "<< duration <<'\n';

    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // The Function Method
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    someClass testClass;

    // START CLOCK
    start = std::clock();

    testClass.someFunction(N);

    // END CLOCK
    duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
    std::cout<<"Member Function Time (seconds): "<< duration <<'\n';

    return 0;

    }

    最佳答案

    我稍微重新编写了您的代码,如下所示:

    #include <iostream>
    #include <chrono>
    #include <cmath>

    class someClass {
    int n, i; // internal class loop indeces
    double foo[1000];
    int I = ::std::floor(sizeof(foo)/sizeof(foo[0])); // number of elements in foo
    public:
    void someFunction(int);
    };

    void someClass::someFunction(int N)
    {
    for(n=N; n--; ) {
    for(i=I; i--; ) {
    foo[i] += 1;
    foo[i] *= .5;
    }
    }
    }


    int main()
    {

    // this was initially an audio processing problem
    // Essentially, process a minute of audio

    int N = 44.1e3 * 60;

    {
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /// The Explicit Method
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    int n, i; // loop indeces
    double bar[1000];
    int I = floor(sizeof(bar)/sizeof(bar[0]));

    // START CLOCK
    auto start = ::std::chrono::high_resolution_clock::now();


    // Exactly what is defined in the function 'someFunction' above
    for(n=N;n--; ){
    for(i=I;i--; ){
    bar[i]+= 1;
    bar[i]*=.5;
    }
    }

    // END CLOCK
    auto end = ::std::chrono::high_resolution_clock::now();

    std::chrono::duration<double> duration_secs = end - start;

    std::cout<<"Explicit Method Time (seconds): "<< duration_secs.count() <<'\n';
    }

    {
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // The Function Method
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    someClass testClass;

    // START CLOCK
    auto start = ::std::chrono::high_resolution_clock::now();

    testClass.someFunction(N);

    // END CLOCK
    auto end = ::std::chrono::high_resolution_clock::now();

    std::chrono::duration<double> duration_secs = end - start;
    std::cout<<"Member Function Time (seconds): "<< duration_secs.count() <<'\n';
    }

    return 0;
    }

    现在,我得到以下输出:
    $ /tmp/a.out 
    Explicit Method Time (seconds): 3.89e-07
    Member Function Time (seconds): 1.46e-07

    因此,对我来说,显式方法要慢得多。尽管它们仍然时间太短,所以几乎不值得测量。两者都在数百纳秒的数量级。令人印象深刻的是计时器具有足以测量的高分辨率。

    那么,下一个问题是,您正在使用哪个编译器?您正在编译什么平台?

    关于您的代码,还有很多事情是次优的。我刚刚清理了包含文件,使用了C++ 11中的 ::std::chrono进行计时,并为计时您的内联版本和成员函数版本做了明确的范围。

    我在gcc 7.2上使用-O3进行了编译。由于它使用未初始化的数组,因此它仍然包含未定义的行为。通过查看代码,gcc意识到甚至从未使用过数组,并且没有生成任何代码。因此,基本上,是对 now的背对背调用。内联版本和成员函数之间的时间差可以完全归因于基本舍入误差。

    因此,答案是,您的代码仍然没有显示您正在谈论的问题,并且您仍然没有提供足够的详细信息。 :-)或者,答案就在您使用的编译器和提供的选项中。

    关于c++ - 当迭代器是类成员时,为什么在C++中for循环变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47082161/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com