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,输入以下命令将软件包上传到服务器:
然后在服务器创建GCC for openEuler安装目录,并把软件包移动到安装目录下:

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

接下来需要配置环境变量,这里我选择了编辑/etc/profile文件。
a.在/etc/profile文件末尾添加以下内容:

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

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

②使用GCC for openEuler的特色优化功能
我主要是尝试了部分反馈优化和结构体优化。
反馈优化
1.准备源代码sort.c

2.PGO优化
使用GCC for openEuler编译程序并执行,可以看到优化前性能基线为2317ms:
添加PGO插桩所需编译选项“-fprofile-generate”,得到插桩二进制并执行,收集profile:

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

利用profile,编译优化后的二进制,可以添加-fopt-info选项来查看编译器执行了哪些优化决策:
最后执行优化后的二进制,就可以看到优化后的效果,我们的执行时间明显缩短了:

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

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

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

结构体优化
这里我们准备好用例a.c:

并手动优化其结构体为:
得到优化后的b.c:

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

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

对比手动优化前后的运行时间,速度比约为1.119。
也可以对a.c分别进行开关优化的编译,执行后查看效果:

可以看到通过开启结构体成员重排优化,能得到和手动优化相似的优化效果。
③实验心得
通过本次实验,我不仅成功安装了GCC for openEuler,还通过尝试反馈优化和结构体优化,对GCC for openEuler的多种编译优化能力有了更深的了解!
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,输入以下命令将软件包上传到服务器:
然后在服务器创建GCC for openEuler安装目录,并把软件包移动到安装目录下:
进入压缩包目录,并解压缩软件包:
接下来需要配置环境变量,这里我选择了编辑/etc/profile文件。
a.在/etc/profile文件末尾添加以下内容:
b.注意!!!编辑完成后,一定要执行命令让环境变量生效:
最后,可以查看一下GCC for openEuler版本,返回版本信息就证明我们的GCC for openEuler已安装成功啦!
②使用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.PGO优化
使用GCC for openEuler编译程序并执行,可以看到优化前性能基线为2317ms:
添加PGO插桩所需编译选项“-fprofile-generate”,得到插桩二进制并执行,收集profile:
我们可以通过gcov工具查看收集到的profile信息:
利用profile,编译优化后的二进制,可以添加-fopt-info选项来查看编译器执行了哪些优化决策:
最后执行优化后的二进制,就可以看到优化后的效果,我们的执行时间明显缩短了:
3.BOLT优化
源码还是sort.c,这次我们利用profile,编译AutoBOLT优化后的二进制:
执行优化后的二进制,看看优化效果:
这里还可以利用AutoBOLT获取的profile执行BOLTuse模式:
结构体优化
这里我们准备好用例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; }并手动优化其结构体为:
struct arc { double b; double c; double d; double f; double g; double h; double i; int a; short e; };得到优化后的b.c:
然后对a.c和b.c进行编译:
执行手动优化结构体的优化效果:
对比手动优化前后的运行时间,速度比约为1.119。
也可以对a.c分别进行开关优化的编译,执行后查看效果:
可以看到通过开启结构体成员重排优化,能得到和手动优化相似的优化效果。
③实验心得
通过本次实验,我不仅成功安装了GCC for openEuler,还通过尝试反馈优化和结构体优化,对GCC for openEuler的多种编译优化能力有了更深的了解!