开发者
资源
openEuler - 实验三:GCC-for-openEuler
openEuler - 实验三:GCC-for-openEuler
发表于2025/07/11
1310

openEuler - 实验三:GCC-for-openEuler

GCC for openEuler编译器是面向鲲鹏和openEuler生态的优选高性能编译器,基于开源GCC(GNU Compiler Collection,GNU编译器套装)开发和全场景优化,生态成熟度高。

这个实验主要就是面向GCC for openEuler编译器,包括如何安装GCC for openEuler以及使用GCC for openEuler的特色优化功能。

①安装GCC for openEuler

从官网(ExaGear|毕昇编译器|毕昇JDK|GCC-下载-鲲鹏社区)下载软件包gcc-12.3.1-2025.06-aarch64-linux.tar.gz,在本地软件包所在文件夹打开cmd,输入以下命令将软件包上传到服务器:

scp gcc-12.3.1-2025.06-aarch64-linux.tar.gz root@服务器公网IP:/root/

然后在服务器创建GCC for openEuler安装目录,并把软件包移动到安装目录下:

mkdir -p /opt/aarch64/compiler
mv /root/gcc-12.3.1-2025.06-aarch64-linux.tar.gz ./

1-设置安装目录.png

进入压缩包目录,并解压缩软件包:

tar -xf gcc-12.3.1-2025.03-aarch64-linux.tar.gz

1-解压缩软件包.png

接下来需要配置环境变量,这里我选择了编辑/etc/profile文件。

a.在/etc/profile文件末尾添加以下内容:

export PATH=/opt/aarch64/compiler/gcc-12.3.1-2025.03-aarch64-linux/bin:$PATH
export INCLUDE=/opt/aarch64/compiler/gcc-12.3.1-2025.03-aarch64-linux/include:$INCLUDE
export LD_LIBRARY_PATH=/opt/aarch64/compiler/gcc-12.3.1-2025.03-aarch64-linux/lib64:$LD_LIBRARY_PATH

1-配置环境变量.png

b.注意!!!编辑完成后,一定要执行命令让环境变量生效:

source /etc/profile

1-环境变量生效.png

最后,可以查看一下GCC for openEuler版本,返回版本信息就证明我们的GCC for openEuler已安装成功啦!

gcc --version

1-gcc--version.png

②使用GCC for openEuler的特色优化功能

我主要是尝试了部分反馈优化和结构体优化。

反馈优化

1.准备源代码sort.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#define ARRAY_LEN 30000

static struct timeval tm1;

static inline void start() {
    gettimeofday(&tm1, NULL);
}

static inline void stop() {
    struct timeval tm2;
    gettimeofday(&tm2, NULL);
    unsigned long long t = 1000 * (tm2.tv_sec - tm1.tv_sec) +\
                           (tm2.tv_usec - tm1.tv_usec) / 1000;
    printf("%llu ms\n", t);
}

void bubble_sort (int *a, int n) {
    int i, t, s = 1;
    while (s) {
        s = 0;
        for (i = 1; i < n; i++) {
            if (a[i] < a[i - 1]) {
                t = a[i];
                a[i] = a[i - 1];
                a[i - 1] = t;
                s = 1;
            }
        }
    }
}

void sort_array() {
    printf("Bubble sorting array of %d elements\n", ARRAY_LEN);
    int data[ARRAY_LEN], i;
    for(i=0; i<ARRAY_LEN; ++i){
        data[i] = rand();
    }
    bubble_sort(data, ARRAY_LEN);
}

int main(){
    start();
    sort_array();
    stop();
    return 0;
}

2-sort.c.png

2.PGO优化

使用GCC for openEuler编译程序并执行,可以看到优化前性能基线为2317ms:

gcc -O2 -o baseline sort.c
./baseline

添加PGO插桩所需编译选项“-fprofile-generate”,得到插桩二进制并执行,收集profile:

gcc -O2 -o pgoing sort.c -fprofile-generate
ls
./pgoing
ls

3-PGO优化.png

我们可以通过gcov工具查看收集到的profile信息:

gcov-dump pgoing-sort.gcda

3-gcov.png

利用profile,编译优化后的二进制,可以添加-fopt-info选项来查看编译器执行了哪些优化决策:

gcc -O2 -o pgoed sort.c -fprofile-use -fopt-info

最后执行优化后的二进制,就可以看到优化后的效果,我们的执行时间明显缩短了:

./pgoed

3-profile.png

3.BOLT优化

源码还是sort.c,这次我们利用profile,编译AutoBOLT优化后的二进制:

gcc -g -O2 -o AutoBOLT sort.c -fprofile-use -fauto-bolt -Wl,-q -fopt-info

4-BOLT优化.png

执行优化后的二进制,看看优化效果:

./baseline
./AutoBOLT

4-优化效果.png

这里还可以利用AutoBOLT获取的profile执行BOLTuse模式:

gcc -g -O2 -o BOLTuse sort.c -fbolt-use=AutoBOLT.fdata -Wl,-q
./BOLTuse

4-profile.png

结构体优化

这里我们准备好用例a.c:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct arc
{
  int a;
  double b;
  double c;
  double d;
  short e;
  double f;
  double g;
  double h;
  double i;
} arc_t;
const int MAX = 10000000;

int main ()
{
  arc_t* arcs = (arc_t*) calloc (MAX, sizeof (arc_t));
  time_t start = clock();
  for (int i = 0; i < MAX; i++)
    {  
      arcs[i].a = 1;
      arcs[i].i = 2;
    }
  for (int i = 0; i < MAX; i++)
    {  
      if (arcs[i].a != 1 || arcs[i].i != 2)
        abort();
    }
  time_t end = clock();
  printf("The execution used %f ms.\n", difftime(end, start));
  return 0;
}

5-a.c.png

并手动优化其结构体为:

struct arc
{  
  double b;
  double c;
  double d;  
  double f;
  double g;
  double h;
  double i;
  int a;
  short e;
};

得到优化后的b.c:

5-b.c.png

然后对a.c和b.c进行编译:

gcc -O3 a.c -o base
gcc -O3 b.c -o test1

5-编译.png

执行手动优化结构体的优化效果:

./base
./test1

5-手动优化结构体效果.png

对比手动优化前后的运行时间,速度比约为1.119。

也可以对a.c分别进行开关优化的编译,执行后查看效果:

gcc -O3 a.c -o base
gcc -O3 -flto -fwhole-program -flto-partition=one -fipa-reorder-fields a.c -o test2
./base
./test2

5-开关优化.png

可以看到通过开启结构体成员重排优化,能得到和手动优化相似的优化效果。

③实验心得

通过本次实验,我不仅成功安装了GCC for openEuler,还通过尝试反馈优化和结构体优化,对GCC for openEuler的多种编译优化能力有了更深的了解!

收藏举报
Level 1
0
帖子
0
粉丝
0
获赞