我如何通过GCC编译器优化创建静态库?

问题描述 投票:-1回答:1

我有一个函数来计算C ++中的点积。我想使用-O3编译器优化来编译此函数。我的代码库中的其余代码都是使用-O0编译的。为此,我创建了一个包含函数的静态库,并使用-O3编译了该库。然后,我将库链接到我的代码。但是我没有从库中获得优化。

test.cpp

#include "config.h"
int multiply(uint128 *X1, uint128 *Y1, uint128 &ans, int input_length)
{
    int i=0;
    ans = 0;
    if (input_length > 4)
    {
        for (; i < input_length - 4; i += 4)
        {
            ans += X1[i] * Y1[i];
            ans += X1[i + 1] * Y1[i + 1];
            ans += X1[i + 2] * Y1[i + 2];
            ans += X1[i + 3] * Y1[i + 3];
        }
    }
    for (; i < input_length; i++)
    {
        ans += X1[i] * Y1[i];
    }    
    return 0;
}
int main()
{
    int len = 500, wrapper = 50;
    uint128 a[len], b[len], ans;
    auto start = time_now, end = time_now;
    long long ctr = 0;
    for(int t = 0; t < wrapper; t++)
    {
        for(int i =0; i < len; i++)
        {
            a[i] = rand();
            b[i] = rand();
        }
        start = time_now;
        multiply(a, b, ans, len);
        end = time_now;
        ctr += std::chrono::duration_cast<std::chrono::nanoseconds>(end-start).count();
    }
    cout<<"time taken: "<<ctr<<endl;
}
Compilation:
g++ -O3 test.cpp -std=c++11
./a.out
time taken: 1372

optimized.hpp

#ifndef OPTIMIZED_HPP
#define OPTIMIZED_HPP
#include <bits/stdc++.h>
using namespace std;
typedef __uint128_t uint128;


int multiply(uint128 *X1, uint128 *Y1, uint128 &ans, int input_length);
#endif

main.cpp

#include "optimized.hpp"
typedef __uint128_t uint128;

#define time_now std::chrono::high_resolution_clock::now()

int main()
{

    int len = 500, wrapper = 50;
    uint128 a[len], b[len], ans;

    auto start = time_now, end = time_now;
    long long ctr = 0;

    for(int t = 0; t < wrapper; t++)
    {
        for(int i =0; i < len; i++)
        {
            a[i] = rand();
            b[i] = rand();
        }

        start = time_now;
        multiply(a, b, ans, len);
        end = time_now;
        ctr += std::chrono::duration_cast<std::chrono::nanoseconds>(end-start).count();
    }
    cout<<"time taken: "<<ctr<<endl;

    return 0;
}
Compilation:
(the name of the library file is optimized.cpp)
g++ -O3 -g -std=c++11 -c optimized.cpp
ar rcs libfast.a optimized.o
g++ main.cpp libfast.a -std=c++11 -O3
./a.out 
time taken: 36140
c++ c++11 gcc static-libraries compiler-optimization
1个回答
0
投票

恐怕您犯了上课的脚步:我优化了试图计时的功能。我们都做了一次。

您已经优化了程序-O3。编译器发现程序忽略multiply的返回值。它还具有multiply的定义并观察到,除了(忽略的)返回值之外,主体没有外部影响。所以这行:

multiply(a, b, ans, len);

也可能是:

(void)0;

和优化器将其剔除。

您可以通过修改程序来纠正此问题,以便它使用返回值multiply的值总是以某种方式有助于程序的输出。

但是那还不够。 -O3优化test.cpp时编译器可以看到multiply的定义仍然要与main.cpp的相同优化相比,这是一个主要的信息优势,其中multiply只是对黑匣子的外部引用。

multiply有意义地测量-O3的速度您必须在-O0优化中针对其速度进行优化每种情况在其他条件相同的情况下。所以至少这样做:

$ g++ -Wall -Wextra -pedantic -c -O0 -o mult_O0.o optimized.cpp
$ g++ -Wall -Wextra -pedantic -c -O3 -o mult_O3.o optimized.cpp
$ g++ -Wall -Wextra -pedantic -c -O3 -o test.o test.cpp
test.cpp: In function ‘int main()’:
test.cpp:13:13: warning: ISO C++ forbids variable length array ‘a’ [-Wvla]
   13 |     uint128 a[len], b[len], ans;
      |             ^
test.cpp:13:21: warning: ISO C++ forbids variable length array ‘b’ [-Wvla]
   13 |     uint128 a[len], b[len], ans;
      |                     ^

((您可能会在意这些警告)

$ g++ -o tmult_O0 test.o mult_O0.o
$ g++ -o tmult_O3 test.o mult_O3.o
$ ./tmult_O0
time taken: 228461
$ ./tmult_O3
time taken: 99092

这表明-O3正在执行其工作。

如果这样,您不需要需要使用返回值multiplytest.cpp的值,因为编译器现在看不到黑盒multiply(a, b, ans, len)没有副作用,无法剔除它。

© www.soinside.com 2019 - 2024. All rights reserved.