使用不同的编译器编译 Skia,性能差距居然这么大

Skia 是一个开源的 2D 图形库,提供路径、文本、图像和渲染等图形处理功能。它最初由 Skia Inc. 开发,后来被 Google 收购,并用在多个 Google 的产品中,包括 Chrome 浏览器和 Android 操作系统中。从事 Android 系统开发的同学应该对 Skia 不陌生,Skia 小巧高效,提供了一套丰富的API,支持多种 CPU 架构和 GPU 加速渲染,支持 Windows、Linux、Mac OS、Android 等操作系统,是跨平台图应用开发的理想选择,广泛应用于移动应用、游戏和专业图形设计工具中。

之前都是在 Android 系统上使用 Skia,最近由于项目需要,需要在 Windows 上使用 Skia 进行图形处理,所以就按照文档在 Windows 下编译出 Skia 图形库。

在 Skia 的官方文档上有这样一句话:

Skia uses generated code that is only optimized when Skia is built with clang. Other compilers get generic unoptimized code.

开始看到这样一句话不以为然,想想编译器优化差别能有多大呢?再说官方首先介绍的编译方法也是使用 Visual Studio 2017 或 Visual Studio 2019。在 Windows 下进行 C++ 开发,程序员首先想到的应该是微软的 Visual C++(曾经有 Borland 的 C++ Builder 与之抗衡)。项目中虽然使用的是 Qt,但在 Windows 下,依然使用的是 MSVC 编译器。所以我想也没有想,就选择了使用 Visual C++ 的编译器 来编译 Skia。

按照文档的步骤下载 Skia 源码,选择了 Chrome/m122 这个分支,接下来下载第三方库、工具等等,这里就不展开,最后一步是编译 Skia。前面说过了,Skia 支持多种 CPU 架构和多种 GPU 加速渲染方式,所以支持多种编译参数。Skia 采用了 gn 构建系统,提供了超级多的参数来支持各种操作系统、编译器和各种定制裁剪。比如最开始我编译的 Skia.lib 库有 500 多 M,最后调整一些参数,编译出来的 Skia.lib 只有 20 多 M。下面是我最终使用 MSVC 编译器编译 Skia 的参数:

bin\gn gen out\Release_msvc --args="extra_cflags=["/MT"] win_sdk="C:\Program Files (x86)\Windows Kits\10" win_sdk_version="10.0.20348.0" win_vc="c:\Program Files\Microsoft Visual Studio\2022\Community\VC" is_debug=false is_official_build=true skia_use_system_expat=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false skia_use_system_harfbuzz=false skia_use_system_icu=false skia_enable_skparagraph=true skia_enable_skshaper=true skia_enable_skunicode=true

其中:

win_sdk: 如果Windows sdk 没有安装在默认位置,需要指定此参数 win_sdk_version: 指定 sdk 版本,如果没有指定,会使用最高版本 win_vc: 如果Visual Stuido 没有安装到默认位置,需要指定此参数 is_official_build: 一般选择false。如果只编译skia库自身,可以选择true,但是jpeg、png等库需要提前准备 is_component_build: false,编译为静态库。true,编译为动态库

使用编译出来的 Skia,使用开源的一个软件 https://github.com/xland/ScreenCapture 测试了一下,发现有严重的性能问题,鼠标移动有明显的延迟,但是这个软件发布的二进制文件,却流畅得很。

首先怀疑的是 Skia 没有开启 GPU 加速,Skia 编译加上 skia_use_gl=true 开启 OpenGL 加速,也没有提升,后来看了一下这个项目的源码,其实是没有启用 GPU 加速绘制的。

接着尝试调整 Skia 的编译选项,但没有什么效果。

没有办法,我抱着试试的心态问了一下作者,在 github 项目的 discuss 区留言,问了一下作者使用怎样编译出来的 Skia,没想到作者很快给了回复:

b86f1524b351b9d150f0f15d0683b6ef.png

按照回复,我下载了 clang 编译器,并使用了如下编译参数:

bin\gn gen out\release_clang --args="clang_win="D:\sdk\clang+llvm-18.1.6-x86_64-pc-windows-msvc" clang_win_version="18" cc="clang" cxx="clang++" extra_cflags=["/MT"] is_debug=false is_official_build=true skia_use_system_expat=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false skia_use_system_harfbuzz=false skia_use_system_icu=false skia_enable_skparagraph=true skia_enable_skshaper=true skia_enable_skunicode=true"

然后再编译 ScreenCapture 源码,果然程序流畅了很多。再次感谢 ScreenCapture 开源项目的作者 xland。

计算机硬件的发展日新月异,例如 Intel 的酷睿处理器已迈入第 14 代,而现代电脑的标配内存通常起步于 16GB。尽管如此,现代计算机的运行速度虽较十年前提升百倍,用户体验却似乎未见显著改进。这种现象可以通过早年的安迪-比尔定律来解释,该定律揭示了硬件升级与软件需求之间的矛盾:硬件性能的提升往往被新软件的需求迅速消耗。

安迪-比尔定理 (Andy and Bill’s Law)是对IT产业中软件和硬件升级换代关系的一个概括。原话是 “Andy gives, Bill takes away.(安迪提供什么,比尔拿走什么。)” 安迪指英特尔前CEO安迪·格鲁夫,比尔指微软前任CEO比尔·盖茨,这句话的意思是,硬件提高的性能,很快被软件消耗掉了。

不仅仅是 Windows 操作系统如此,应用软件也是如此。虽然新的软件功能比以前的版本强了一些,但是,增加的功能绝对不是和它的大小成比例的。现在随便一个软件都是几百兆,甚至好几个 G。

现代程序员开发软件,不会使用 C/C++ 从头写起,也很少考虑性能,而是采用一大堆框架、叠加很多中间层,这当然会导致软件越来越庞大。当然,从可维护性和开发速度上来讲,这种开发模式没有什么不好。现代软件越来越复杂,要满足的需求越来越多,如果都使用 C/C++ 来写,也不现实。所以现在普遍的模式都是业务层使用 Java、Python、JS 之类的快速开发语言编写,核心功能以及追求高性能的组件仍然使用 C/C++ 编写。在 AI 领域,虽然 Python 语言是当之无愧的 No. 1,但 AI 框架的核心,基本上都是使用 C/C++。

在这里并不是过分强调软件优化,毕竟在软件开发领域,有一句箴言:

过早优化是万恶之首。

“过早优化是万恶之首”这句话最初由计算机科学家唐纳德·克努斯(Donald Knuth)提出,完整的说法是:“Premature optimization is the root of all evil”。这句话强调在软件开发过程中,过早地进行优化可能导致代码复杂度增加、降低代码的可读性和可维护性,而且往往在不了解系统的真正瓶颈前,盲目优化可能会浪费大量的时间和资源。

  • 开发者可能在项目需求和系统瓶颈尚不明确时,就开始对代码进行优化。这种情况下,优化往往基于假设而非实际数据,可能导致优化工作偏离了真正需要改进的方向。

  • 过早优化可能使代码变得复杂难懂,增加了后续维护和迭代的难度。

  • 从成本上考虑,还可能耗费大量的时间和资源,而这些投入在项目早期可能并不划算。

关于软件优化, AI 给出了如下建议:

  1. 基于性能分析优化:在进行优化之前,使用性能分析工具来确定系统的实际瓶颈。只有基于实际数据的优化,才是有效和必要的。

  2. 逐步优化:在项目开发的早期阶段,可以关注于代码的正确性和功能完整性。待功能稳定后,再根据实际需要逐步进行性能优化。

  3. 保持代码的可读性和简洁性:优化不应以牺牲代码的可读性和可维护性为代价。清晰和简洁的代码更容易被理解和维护。

  4. 优化的优先级:对于影响用户体验的性能问题优先进行优化,例如加载时间、响应速度等。对于后端处理,如能满足业务需求,可适当延后优化。

  5. 使用成熟的工具和库:利用已经过优化的第三方库和工具,可以避免重复造轮子,同时利用社区的力量来提升软件性能。

真的没有想到,编译器对性能有如此大的影响,你在工作中会进行性能优化吗?有哪些优化措施?欢迎留言讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/645090.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Science 基于尖峰时序编码的模拟神经触觉系统,可实现动态对象分类

快速处理和有效利用手与物体交互过程中产生的动态触觉信号(例如触摸和抓握)对于触觉探索和灵巧的物体操作至关重要。将电子皮肤(e-skins)推进到模仿自然触觉的水平,是恢复截肢者和瘫痪患者丧失的功能的可行解决方案&am…

北核论文完美复现:自适应t分布与动态边界策略改进的算术优化算法

声明:文章是从本人公众号中复制而来,因此,想最新最快了解各类智能优化算法及其改进的朋友,可关注我的公众号:强盛机器学习,不定期会有很多免费代码分享~ 目录 原始算术优化算法 改进点1:引入…

深入探索MySQL SELECT查询:从基础到高级,解锁数据宝藏的密钥

系列文章目录 更新ing... MySQL操作全攻略:库、表、数据、事务全面指南深入探索MySQL SELECT查询:从基础到高级,解锁数据宝藏的密钥MySQL SELECT查询实战:练习题精选,提升你的数据库查询技能PyMySQL:连接P…

【电路笔记】-巴特沃斯滤波器设计

巴特沃斯滤波器设计 文章目录 巴特沃斯滤波器设计1、概述2、Decades和Octaves3、低通巴特沃斯滤波器设计4、滤波器设计 – 巴特沃斯低通5、三阶巴特沃斯低通滤波器在之前的滤波器教程中,我们研究了简单的一阶型低通和高通滤波器,这些滤波器的 RC 滤波器电路设计中仅包含一个电…

Ant design vue的表格双击编辑功能(即双击开始编辑并自动获得焦点,失去焦点时完成编辑)

本文基于Ant Design Vue官方网站的表格(可编辑单元格)(表格 Table - Ant Design Vue (antdv.com))中的样板代码获得双击编辑且获得焦点、失去焦点时完成编辑的功能。 要点: (1)双击时候实现编辑&#xff…

spark实战:实现分区内求最大值,分区间求和以及获取日志文件固定日期的请求路径

spark实战:实现分区内求最大值,分区间求和以及获取日志文件固定日期的请求路径 Apache Spark是一个广泛使用的开源大数据处理框架,以其快速、易用和灵活的特点而受到开发者的青睐。在本文中,我们将通过两个具体的编程任务来展示S…

在CentOS7上安装Oracle11

一、概述 Oracle有两种安装方式,桌面安装和静默安装。这里我采用桌面安装的方式。 不得不说,Oracle真的是我目前为止安装过的最麻烦的软件没有之一,比K8S还麻烦,Oracle,真有你的!废话不多说,臭…

重学java 45.多线程 下 总结 定时器_Timer

人开始反向思考 —— 24.5.26 定时器_Timer 1.概述:定时器 2.构造: Timer() 3.方法: void schedule(TimerTask task, Date firstTime, long period) task:抽象类,是Runnable的实现类 firstTime:从什么时间开始执行 period:每隔多长时间执行一次…

Java | Leetcode Java题解之第100题相同的树

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isSameTree(TreeNode p, TreeNode q) {if (p null && q null) {return true;} else if (p null || q null) {return false;}Queue<TreeNode> queue1 new LinkedList<TreeNode>();…

MySQL——优化

全文搜索最慢 EXPLAIN select * from city; 范围搜索 EXPLAIN select * from city where ID>5 and ID<20; 主键查询 EXPLAIN select * from citywhere ID5; 索引查询 EXPLAIN select * from citywhere CountryCodeNLD; 普通查询 EXPLAIN select * from city where Nam…

C# WPF入门学习(四)—— 按钮控件

上期介绍了WPF的实现架构和原理&#xff0c;之后我们开始来使用WPF来学习各种控件。 一、尝试插入一个按钮&#xff08;方法一&#xff09; 1. VS2019 在界面中&#xff0c;点击工具栏中的视图&#xff0c;在下拉菜单中选择工具箱。 至于编译器中的视图怎么舒服怎么来布置&am…

揭秘Kafka从入门到精通,架构最全详解

Kafka架构最全详解 Kafka&#xff0c;作为关键消息中间件&#xff0c;广泛应用于大型架构与顶尖企业。本篇深入解析Kafka架构&#xff0c;掌握其核心技术要点。 Kafka Apache Kafka 是一个分布式发布-订阅消息系统&#xff0c;由LinkedIn开创的分布式发布-订阅消息系统&#x…

数据仓库与数据挖掘实验练习6-7(实验四2024.5.22)

tips&#xff1a; 列出虚拟环境&#xff1a;conda env list 激活虚拟环境&#xff1a;activate hi 进入jupyter-lab&#xff1a;jupyter lab 练习6 1. 处理字符串空格 发现问题: 使用 values 属性查看数据时&#xff0c;如果发现 Name 列没有对齐&#xff0c;很可能是 Name 左…

008-Linux后台进程管理(作业控制:、jobs、fg、bg、ctrl + z、nohup)

文章目录 前言 1、& 2、ctrl z 3、jobs 4、fg&#xff1a;将后台进程调到前台执行 5、bg&#xff1a;将一个暂停的后台进程变为执行 6、&和nohup 总结 前言 有时候我们需要将一个进程放到后台去运行&#xff0c;或者将后台程序切换回前台&#xff0c;这时候就…

刷代码随想录有感(79):回溯算法——N皇后问题

题干: 代码&#xff1a; class Solution { public:vector<vector<string>> res;void backtracking(vector<string>& chessboard, int n, int row){if(row n){res.push_back(chessboard);return;}for(int col 0; col < n; col){if(isvalid(chessboa…

【吊打面试官系列】Java高并发篇 - ThreadLocal 是什么?有什么用?

大家好&#xff0c;我是锋哥。今天分享关于 【ThreadLocal 是什么&#xff1f;有什么用&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; ThreadLocal 是什么&#xff1f;有什么用&#xff1f; ThreadLocal 是一个本地线程副本变量工具类。主要用于将私有线程和该…

六招搞定,SPA单页面加载速度慢的问题。

众所周知&#xff0c;SPA页面有很多优点&#xff0c;但是首屏加载慢的问题一直被诟病&#xff0c;本文介绍几种解决策略&#xff0c;希望对老铁们有所帮助。 一、SPA页面的独有优势 1. 更快的用户体验&#xff1a; SPA在加载初始页面后&#xff0c;可以在用户与应用程序交互…

看这两位东北圣女美吗?如何描写美女的大长腿?

看这两位东北圣女美吗&#xff1f;如何描写美女的大长腿&#xff1f; 最近署名为懂球娘娘的一篇描写东北圣女的文章火了&#xff0c;文中描述了海棠朵朵与辛芷蕾这两位娇媚动人的角色。其美艳动人的形象和魅力四溢的描写让人为之倾倒。 这种通过文字展现人物魅力的能力让人佩服…

4个宝藏网站,免费即用,办公运营效率利器!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 有很多朋友在日常办公时&#xff0c;需要发送邮件&#xff1b;在新媒体运营、设计及前端开发等工作场合中&#xff0c;都或多或少会遇上图片、视频等文件太大及格式问题需要压缩和转换…

白嫖的在线工具类宝藏网站清单,快点击进来收藏一波

简单整理了一下自己日常经常使用的10个免费工具网站&#xff0c;建议点赞关注收藏&#xff0c;快点分享给小伙伴们&#xff01; 1.奶牛快传:用户体验更好的网盘工具。 https://cowtransfer.com/ 今年开始使用的一款网盘工具&#xff0c;和百度网盘类似,叫奶牛快传&#xff0c;如…