LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   constexpr and performance result (https://www.linuxquestions.org/questions/programming-9/constexpr-and-performance-result-4175734861/)

Mac1ek 03-13-2024 04:38 AM

constexpr and performance result
 
Hi Why constexpr in function giving extremely high performance when i compare to plain function ?

example:

Code:

constexpr auto fib_constexpr(unsigned int n) -> unsigned int {
        return (n <= 1) ? n : fib_constexpr(n - 1) + fib_constexpr(n - 2);
}

auto fib_normal(unsigned int n) -> unsigned int {
        return (n <= 1) ? n : fib_normal(n - 1) + fib_normal(n - 2);
}

this constexpr function giving whole different result in performance

Thank You for answer.

pan64 03-13-2024 05:18 AM

would be nice to demonstrate it somehow. Or at least explain how did you measure it?

Mac1ek 03-13-2024 05:57 AM

Quote:

Originally Posted by pan64 (Post 6489420)
would be nice to demonstrate it somehow. Or at least explain how did you measure it?

Il write simple benchmark for this, i not shure is correct:

Code:

#include <iostream>
#include <chrono>

constexpr auto fib_constexpr(unsigned int n) -> unsigned int {
        return (n <= 1) ? n : fib_constexpr(n - 1) + fib_constexpr(n - 2);
}

auto fib_normal(unsigned int n) -> unsigned int {
        return (n <= 1) ? n : fib_normal(n - 1) + fib_normal(n - 2);
}

auto benchmark_fib_constexpr() -> void {

        auto start = std::chrono::system_clock::now();
        auto end = std::chrono::system_clock::now();

        unsigned int count = 0;
        constexpr unsigned int n = 20;

        for(unsigned int i = 0; i < 10;) {
                fib_constexpr(n);
                ++count;
                end = std::chrono::system_clock::now();
                if(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() >= 1000) {
                        std::cout<<"In second operation count is: "<<count<<std::endl;
                        count = 0;
                        ++i;
                        start = std::chrono::system_clock::now();
                }

        }       
}

auto benchmark_fib_normal() -> void {

        auto start = std::chrono::system_clock::now();
        auto end = std::chrono::system_clock::now();

        unsigned int count = 0;
        unsigned int n = 20;

        for(unsigned int i = 0; i < 10;) {
                fib_normal(n);
                ++count;
                end = std::chrono::system_clock::now();
                if(std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() >= 1000) {
                        std::cout<<"In second operations count is: "<<count<<std::endl;
                        count = 0;
                        ++i;
                        start = std::chrono::system_clock::now();
                }
        }
}


auto main() -> int {
        std::cout<<"CONSTEXPR FIB BENCHMARK"<<std::endl;
        benchmark_fib_constexpr();
        std::cout<<"NORMAL FIB BENCHMARK"<<std::endl;
        benchmark_fib_normal();
        return (0);
}

important is compile with -O2 flag:
Code:

g++ -std=c++11 -O2 test.cpp

then in terminal i have result:
Code:

CONSTEXPR FIB BENCHMARK
In second operation count is: 49968765
In second operation count is: 49981539
In second operation count is: 50005027
In second operation count is: 49964753
In second operation count is: 49948262
In second operation count is: 49992233
In second operation count is: 49954760
In second operation count is: 49976978
In second operation count is: 49989060
In second operation count is: 49987518
NORMAL FIB BENCHMARK
In second operations count is: 131435
In second operations count is: 131457
In second operations count is: 131451
In second operations count is: 130226
In second operations count is: 130350
In second operations count is: 130034
In second operations count is: 129069
In second operations count is: 129363
In second operations count is: 120881
In second operations count is: 126952


NevemTeve 03-13-2024 06:17 AM

That could have been entirely optimized away. The standard benchark method is calculating fib(largeint) modulo 1000000009

pan64 03-13-2024 07:11 AM

yes, n=20 is not really useful, try other numbers too (like 1234567890).

sundialsvcs 03-13-2024 08:43 AM

Since you defined it as a "constant expression," the compiler doesn't have to generate a function at all.

pan64 03-13-2024 11:06 AM

Quote:

Originally Posted by sundialsvcs (Post 6489461)
Since you defined it as a "constant expression," the compiler doesn't have to generate a function at all.

As it was mentioned (and I guess) compiler can optimize it, so I'm not really sure this is the real reason. Furthermore I don't think an additional function call can cause this difference.
Would be nice to see the object code to check it.


All times are GMT -5. The time now is 05:05 AM.