您的位置: > 奇异游戏 >

二进制领域进不去(36氪首发 | 尺物科技获天使轮融资,以二进制级方案解决物联网安全痛点)

导读 二进制领域进不去文章列表:1、36氪首发 | 尺物科技获天使轮融资,以二进制级方案解决物联网安全痛点2、全民免费医疗为什么很难行得通?3、Rust 不适合开发 Web API4、开源被喷,

二进制领域进不去文章列表:

二进制领域进不去(36氪首发 | 尺物科技获天使轮融资,以二进制级方案解决物联网安全痛点)

36氪首发 | 尺物科技获天使轮融资,以二进制级方案解决物联网安全痛点

作者 | 咏仪

编辑 | 苏建勋

36氪获悉,「尺物科技」完成数百万元天使轮融资,投资方为方信资本。本轮融资将投入到现有产品研发,完善公司产品矩阵,增强人才队伍建设等方面。

尺物科技成立于2020年6月,核心成员曾任职于蚂蚁金服、赛门铁克、梆梆安全等国内外一线科技公司核心岗位,是国内最早进入物联网安全领域的安全研究团队之一。

广义物联网包含车联网、工业互联网、智慧能源、智慧交通、智慧城市等场景。无论是我国从2014年开始智能硬件创业浪潮,或是更早之前的互联网基建,其最重要的意义是让大量的设备接入网络,这是物联网生态的基础。据IDC统计,2020年全球物联网行业的市场规模为1.36万亿美元,2015-2020年间复合增长率达17.39%。

越来越多的设备接入网络带来的是巨量的数据,这又涉及到物联网安全问题。在IoT安全层面,除了360、绿盟等传统玩家参与外,从2015年开始,阿里、腾讯等大厂也相继成立物联网安全团队,开发相应解决方案。5G、AI等多种技术在近几年内快速落地,又更加印证了IoT安全的重要性和市场刚需。

尺物科技创始人周亮有十多年嵌入式研发、安全攻防、安全方案架构和团队管理经验,精通IoT安全及移动安全技术。他告诉36氪,当前国内IoT安全已有不少玩家,大家普遍都是在4-5年前相继进入这个市场。随着物联网生态逐渐成熟,在垂直行业相应落地,IoT攻击事件近几年呈高发趋势。

然而,IoT的几个固有属性让安全方案落地非常困难。首先是技术和场景的碎片化过于严重,导致需求碎片化,比如手机、汽车、音箱等等各类终端搭载不同品牌、应用场景、操作系统(如Linux/Android等),终端千变万化,安全厂商难以用统一方案来解决。

纵观近几年物联网安全事件,攻击者对于设备端的攻击,绝大部分是通过逆向固件、逆向应用获取到核心算法与核心协议来完成的。业内主流的IoT设备漏洞挖掘主要依赖人工审计,以代码特征比对,再推出相应防御方案,这类方案效率低且覆盖面窄,会出现大量漏报误报。

周亮表示,不同于以往特征比对的方式,尺物科技主要是抓住了物联网设备中的共性——IoT终端设备70%以上都采取ARM芯片架构,已经覆盖90%以上的技术场景。因此,尺物在创立初期,就投入大量人力物力,自研了一套基于二进制级的应用加固系统。该方案是同时支持控制流混淆和指令集虚拟化,兼顾高安全性和高可用性。

目前,尺物的产品体系主要分为四大块:安全加固、安全检测、威胁感知(主动防御)以及安全服务。

IoT终端安全可以简单分为三个层次,包括芯片层、系统层和应用层。尺物首先从防御开始切入,作用于应用层,入侵性相对较小。

以尺物首先推出的安全加固SaaS为例,终端设备自身风险就包括篡改、木马植入等等,尺物的加固产品能够保证可信的数据环境,保证数据在传输到云端之前是安全可靠的,这对风险认知要求很高——也就是说,要知道有哪些风险才能加固,尺物也实现了自动化筛选这些风险点,并对其对应代码进行保护。再之后,威胁感知则进行动态分析,能够实时感知设备是否被攻击,并对攻击行为进行阻断。

对于客户而言,该方案的好处在于,因为直接面向被保护的应用程序,这一方案通用于各类场景,以SaaS方式提供服务,部署时间快,维护成本低。

另外,现在主流的应用保护方案基本都是基于开源研发,已被攻击者研究多年,安全性相对较弱。在二进制方案下,客户也无需提交源代码或配置开发环境,直接输入设备的二进制文件到加固平台即可,这很大程度上阻断了源代码相关攻击行为。

目前,尺物科技的方案已经初步成熟,并且已经与一批大型客户在洽谈或使用阶段,未来目标是建立一个安全运维平台,不断扩展生态。本轮融资后,尺物科技也将进一步将IoT安全和客户业务相整合。比如近年来快速发展的车联网、智慧政府、安全等场景,尺物科技也会针对性地推出行业方案。

全民免费医疗为什么很难行得通?

#医疗##免费医疗#

医疗领域的话题一直热度居高不下,我们在各种平台和网络上都能看到因为家庭经济的原因无法得到治疗的各种不幸人士,在各大筹款平台上,也能经常看到因为各种意外而导致家庭无力承担的情况。

全民免费医疗,这个声音也一直不绝于耳,甚至于,在每一次医保谈判降低费用的时候,也总有人喊出,索性全免就算了。

在这里,我们简单讨论一下,为什么全民免费医疗是很难行得通的。

首先,我们要对医疗服务下一个定义,在经济学里面,医疗服务是一个奢侈品,并不是一个普通的大众商品。很多人很奇怪,为什么医疗是奢侈品?原因也很简单,医疗服务是需要大量人力物力投入的一对一的服务。不像牛奶面包电视机等,如果需要,可以迅速扩大产能,迅速满足需求。但是医疗不行,即使药品可以迅速扩大产能,但是怎么吃,谁应该吃药,都是需要经过医生诊断来决定的。这种一对一的服务,就从根本上注定了,医疗服务没办法快速提供产能。

更不要说,我们培养一个医生,现在都是动辄博士起步,一个人辛辛苦苦读了三十年书,经过层层筛选和考试,最终成为合格的医生,也就注定了,医生这个群体无法大规模的批量制造,更不要说年长资深的有能力的医生。谁都希望找一个厉害的医生看病,但问题是,由谁来决定厉害的医生给谁看病呢?这是一个很深的伦理和社会问题。

再到社会成本,很多人总说生命是无价的,但是到整个社会,生命就是有价的。我们以癌症为例,几乎所有人都知道是不治之症,死亡率非常高,费用也非常大。那么,谁来决定谁可以活多久呢,如果各种医疗手段全部用上,单人可能需要几百万的费用,并且随着时间的推移越来越多,以2020年我国的癌症人数来算,约有2000万人,一人花100万治疗,就需要20万亿,而我们2020年的全国GDP才100万亿,也就是说,全国人民不吃不喝,一年也就只能负担5个类似的疾病。所有人都知道,这是不可能的。

也有人说,那为什么医保不能报销呢。首先,我们要明白,医保资金是来源于我们自己,医保资金也是有限的。如果要负担如此沉重的医疗支出,除非所有人的所有收入全部上缴进入医保。那无疑是对社会运行的巨大破坏,如果你的工资收入全部要上交,那你还会愿意工作么?还会有人愿意创新么?还会有人愿意奋斗么?

也经常看到的一个论调,是医药企业收得太贵。这一点上,众所周知,医药最重要的成本是研发费用,具体到生产成本,真的很低。问题是,如果研发费用回不来,我们的医药就不会发展了。简单来说,之前一段时间很出名的治疗小儿脊髓性肌肉萎缩症的药,诺西那生钠,一针高达70万人民币,我看到很多人批评医药公司卖的太贵。问题来了,如果没有医药公司,这个病是没救的,是无法治好的。换句话来说,如果没有这个药,患者只能等死。是医药公司给了他们生存的希望,但是,医药公司研发的投入以及合理的利润都需要从这个病并不多的患者身上赚回来。如果不让他们卖高价,以后没有哪个医疗企业愿意投入巨额资金去研发新药。如果让他们卖高价,注定有很多条件不够的家庭无法负担。这也是一个巨大的伦理问题。如果没有更好的方式决定谁能获得治疗,谁不能获得治疗,只能由市场来决定。

此外,免费还会带来一个问题,就是过度使用或者滥用。就像我们经常看到的现象,什么东西被浪费的最多?什么食物被扔得最多?答案都是免费的。我们经常看到免费提供的食物,被扔的到处都是,免费提供的公园,被破坏的一塌糊涂。就是因为免费,很多人也不会关心适度的问题。在美国,过度医疗已经是一个很严重的问题,美国人真的看不起病么?不是的。是因为美国的医疗体系长期在有保险的情况下过度地采用各种高昂的医疗方式。导致在美国,一旦你超出了你的保险范围或者没有医疗保险,一个小病就能让你倾家荡产。

同样的,如果什么都免费,很多人去医院,排个胸片就能解决的问题,就会让医生拍CT,拍核磁,反正不要钱。就像我们现在在北方一些原本的国营单位的医院看到的,一些退休的老头老太,他们当年都是免费医疗的,有事没事跑去医院开点药,有事没事去拍个片子。把医院当免费药房,家里需要什么就去医院开,医生不给也不行,拿他们毫无办法。换句话来说,他们这种行为就是对医保的极大浪费。

因此,我们需要纠正一个观念,免费并不能很好地解决问题,尤其是会带来巨大伦理挑战的医疗领域。

Rust 不适合开发 Web API

Rust 是一门神奇的编程语言,有非常好的 CLI 工具,比如ripgrep和exa。像 Cloudflare 这样的公司正在使用并鼓励人们写Rust来运行微服务。Rust 编写的软件可能比 C 或 C 更安全、更小、更简洁。

如果我正在编写一个地理编码器、一个路由引擎、一个实时消息平台、一个数据库或一个 CLI 工具,Rust 最合适。

但去年,我试图用 Rust 写一个传统网站的纯 API 服务,Rust 就不合适了。

缺失很多小功能

Rust 有大量的 Web 服务框架、数据库连接器和解析器。但搭建身份验证服务方面只有非常低层次的组件。Node.js 有passport.js,Rails 有devise,Django 有开箱即用的身份验证模型,在 Rust 中,你需要学习如何将共享 Vec 转换到底层加密库才能构建这个系统(译者注,Vec 是一个动态数组,只会自动增长而不会自动收缩。区别于 Array,Vec 具有动态的添加和删除元素的能力,并且能够以 O(1)的效率进行随机访问。Vec 的所有内容项都是生成在堆空间上的,可以轻易的将 Vec 移出一个栈而不用担心内存拷贝影响执行效率,毕竟只是拷贝栈上的指针)。有些库试图解决这个问题,比如libreauth,但它才刚刚开始开发。还有很多类似的 Web 框架问题。

SDK 呢?在主流编程语言中,你可以通过一个官方库来接入 Google 云服务、AWS 或 Stripe。这些官方库大都很棒。例如,aws-sdk-js和Stripe库的设计和维护得非常好。

Rust 就不这样,只有少许第三方库,但以这些服务的开发速度,它们真的能够提供高质量的体验吗?

有人会说好吧,X 编程语言太好了,你可以在周末自己写一个 SDK!我必须回答,不。

Rust 的生态系统在其它领域非常丰富。用于构建 CLI、管理并发性、使用二进制数据和底层解析器的 crates 令人印象深刻,非常棒。

Rust 编译器比以前快,但仍然很慢

我一直在看Nicholas Nethercote的博客,描述了 Rust 团队如何优化编译器,让它更快!

但与其它编程语言相比,用它构建网站会很慢。它比编译型编程语言 Go 慢得多,也比解释型编程语言 JavaScript、Ruby 和 Python 等慢得多。

一旦代码被编译,一切就变得非常棒了!但在我的情况下,甚至基本 API 功能都不完整,一个不复杂的系统——居然花了 10 多分钟来编译。Google代码构建的硬件配置很差,每次都会超时,我啥都编译不了。

只要不重建缓存依赖项,缓存就有意义。也许减少依赖会加快 Rust 项目编译。但就像serde,几乎所有人都使用的 JSON 和其它序列化/反序列化程序占用了大量的编译时间。我们是否应该用编译速度更快但缺乏大量文档和生态系统支持的东西来取代 serde?这种取舍非常糟糕。

Rust 很复杂

Rust 让你从代码维度进行思考,这对系统编程来说非常重要。它让你思考如何共享或复制内存,思考真实但不太可能的小概率事件,并确保妥善处理它们,帮你编写各种各样的高效代码。

这些担忧都是合理的,但是对于大多数 Web 应用程序来说,它们并不是最重要的关注点,以流行的惯性思考会导致不正确的假设。

就拿 Rust 的安全性来说吧。这是它宣传语中的重要部分,这是绝对正确的:Rust 的承诺安全和底层两者兼而有之——它可以在没有垃圾收集器的情况下工作,同时防止基于内存的漏洞。当你读到“安全”的时候,想想 Rust 的竞争对手 C 吧。C 语言中的代码可以引用任意内存,很容易溢出和出错。Rust 代码可以和 C 代码一样快,但是可以保护内存访问,而不需要垃圾收集器或某种运行时检查。

但是 Rust 的内存规则并不比 Node.js 或 Python 更安全,用 Rust 编写的 Web 应用程序在系统上不会比 Python 或 Ruby 应用程序安全。带有垃圾收集器的高级编程语言通常为避免这类漏洞利用和错误而付出性能损失。不能在 JavaScript 中引用未初始化的内存,因为 JavaScript 中不进行内存间的引用。

旁注:这是在描述 Node.js 和其它系统的设计目标——它们确实偶尔会有 bug。Node.js 的缓存对象,就值得读一读。

你要是问一些人,他们会说如果使用不安全的代码,Rust 相比带有内存回收的编程语言是不安全的——包括最流行的 Web 框架 Actix(译者注,Actix 是 Rust 的 Actor 异步并发框架,基于 Tokio 和 Future,开箱具有异步非阻塞事件驱动并发能力,其实现低层级 Actor 模型来提供无锁并发模型,而且同时提供同步 Actor,具有快速、可靠,易可扩展https://actix.rs/),因为不安全代码允许原始指针的延迟。

如果你正在写一个视频游戏,暂停执行垃圾收集是不好的。如果你在编写微控制器代码,任何内存“开销”或浪费都是非常糟糕的。但是大多数 Web 应用程序可以节省一点内存开销来换取生产性能。

Rust 的其它属性面对的争议几乎一样。它的并发特性是太神奇了,如果你在做一些复杂的事情,需要快速响应,这当然很棒。但如果情况不是这样呢?至少可以说,Rust 的异步生态系统面临着很大挑战:各种不相关的领域中有着不同的异步实现,比如tokio。

相比较之下,Python 的 Tornado 和 Twisted 异步实现的很奇怪,Node.js 异步实现的很好,但语法都很丑陋。

我确信,Rust 的异步将会稳定和统一,未来会更容易操作,但我现在就要用啊。

Rust 生态系统不是以 Web 为中心的

很多人正在学 Rust,用 Rust 编写 CLI 应用程序或底层代码,并且玩得非常开心。使用 Rust 编写普通 Web 应用程序的人明显少很多。

这是技术选择中的重要部分:是否有人在使用该工具?他们大致在同一个领域吗?不幸的是,Rust 生态系统中许多令人难以置信的令人兴奋的工作与 Web 应用服务器无关。的确存在一些很有前途的 Web 框架——甚至更高层次的框架,但毫无疑问,它们市场很小。即使是主要的 Web 框架 Actix 也只有几个顶尖贡献者。

如果 Rust 以目前的速度增长,那么社区中的 Web 部分将达到一个临界值,但我认为没有足够多的人使用 Rust 作为网站的实用工具。与其它社区相比,有很多公司致力于使用现有的工具来构建 Web 应用程序,这些工具不是最前沿的,但足够将成熟技术与新技术区分开来。

Juniper 的 N 1 次查询

这一部分不仅仅是 Rust,它还涉及 GraphQL 生态系统,Rust 参与这个生态系统就是一个例子。

N 1问题是每个构建 Web 应用程序的人都应该知道的。要点是:你有一页照片(一次查询),你要显示每张照片的作者,会有多少次查询:1,合并照片和作者,或者在检索照片后对每张照片进行查询以获取作者?或者两次,第二次查询 ids 中的 user.id,一次获取所有作者,然后重新设置他们的照片属性。

N 1 查询通常优先使用数据库解决:比如将 N 1 查询改为单个查询,会带来明显的性能优化。我们有很多方法来尝试和解决这些问题:你可以编写 SQL,并尝试使用 CTE 和 JOIN 在单个查询中完成大量工作,就像我们在 Observable 中所做的那样,或者使用像 ActiveRecord 这样的 ORM 层将 N 1 查询转换为可预测查询的快速方法。

Juniper 是一个用于 Rust 应用程序的 GraphQL 服务。GraphQL 基本上都是由前端应用程序定义查询,而不是后端。给它一系列可以查询的东西,然后应用程序(React 或其它)将任意查询发送到后端。

这会让后端变得复杂。任何 SQL 级别的优化都不可能做到——你的服务器正在编写动态 SQL,优化只能依赖 GraphQL 服务,但它不会总是有效。例如:Juniper 默认情况下执行的是 N 1 查询,解决方案dataloader还比较粗糙且需要单独维护。因此,最终您将拥有一个非常快的应用程序层,但它所有的时间都花在了极其低效的数据库查询上。

总之,GraphQL 与 NoSQL 数据库配合使用效果非常好,它可以快速为这些类型的请求提供服务。我确信 Facebook 内部有一些特定的数据库与 GraphQL 结合在一起使用效果非常棒,但业内其他企业则非常依赖 Postgres 和同类产品。

一些注意事项

首先,本文提到的问题并不针对在通用场景使用 Rust,只针对将 Rust 用于特定目标和生态系统,简单说就是 Web API。

注意事项 1:一般情况下,你可以用任何编程语言搭建网站,还记得基于C 实现的OkCupid吗?(译者注,OkCupid 是美国一个大型线上交友网站)还有一个非常流行的星象应用程序,Co-star,它全部是用 Haskell 编写的。如果你擅长其它编程语言,或者可以招聘到擅长这些编程语言的工程师,你一样可以取得成功。

注意事项 2:我试图构建的是重CRUD(增删改查)的 Web 应用程序 API。它可能不算是一个 Web“服务”——主要是快速、无数次地执行同一个操作,而是一个 Web“应用程序”——执行了许多不同的操作,包含了相当多的业务逻辑。如果你要开发的东西跟我在做的不一样,那我的建议可能就不适合你。如果你需要的是快速执行一两个操作,比如你正在写一个支付网关或语音消息应用程序,那 Rust 可能效果还是不错的。

注意事项 3:这篇文章写于 2021 年 1 月,如果接下来社区继续发展,Rust 将得到持续的改进,会变得更好并更易于 Web 应用程序开发。

总而言之,我真的很喜欢使用 Rust,这是一门美丽的编程语言,有很多很酷的想法。希望很快,Rust 会成为能用来构建我想做的东西的最合适的工具。不过,现在我想做的很多东西都要采用不同特性的编程语言才能更好地运行。

英文原文链接:

https://macwright.com/2021/01/15/rust.html

延伸阅读:

专访京东科技张亮:本土开源需形成吸纳开发者的靶心丨开源创新30人-InfoQ

关注我并转发此篇文章,即可获得学习资料~若想了解更多,也可移步InfoQ官网,获取InfoQ最新资讯~

开源被喷,闭源被疑:方舟编译器怎么这么难?

作者丨赵钰莹

闭源时被质疑是否真的存在这样一个编译器,开源后又被喷技术含量不行,方舟编译器怎么就这么难?本文,鸿蒙开源主管及方舟编译器架构师首次完整公开分享了方舟编译器的基础架构。

1、方舟编译器怎么这么难?

自 8 月 31 日正式开源,方舟编译器的讨论热度达到高潮,知乎话题《如何看待方舟编译器于 2019 年 8 月 31 日开源?》累计被浏览了五百多万次,网友共计发表了八百多条评论。由于本次开源放出的代码较少,不少网友都抛出了疑问,比如运行时方面的计划,开源的原因,开发出来的应用是否只能在华为手机上运行以及未来打算怎么做生态等,十年磨出的方舟编译器,一朝开源怎么就面临这么艰难的境地呢?

事实上,相比于过往十年的研发历程,现在的处境可能还算不上最艰难的。

2009 年,华为第一个编译团队成立,起初是为了无线基站领域的 DSP 性能问题。

2014 年,Open64 的鼻祖 Fred Chow 加入,这对华为后来的编译器发展,包括如今的方舟编译器都产生了重要影响。

2017 年,华为手机的销量非常之高,又开始出现大量新的问题。当时,整个混合执行模式里,解释执行的占比非常高,而执行性能比较低,JIT 在后台生成 JIT 代码的过程又会消耗大量 CPU 资源,编一个函数需要的时间也很长。此外,由于优化不完善,虚拟机的停顿时间非常长,尤其内存不足时,会导致大量卡顿。

基于上述原因,整个团队讨论出两条可行的解决方案:一是在现有虚拟机的基础上修改;二是另起炉灶,重新做一套能够执行 Java 的运行环境和编译器。第一条路相对简单省事,但只能解决部分问题,华为最终选择了第二条路线,这就促成了如今方舟编译器的诞生。

在方舟编译器的设计上,Fred Chow 的一篇论文提供了很好的思路:基于统一的 IR 既支持多种编程语言表示,又支持后端多芯片代码的指定形成。这就构成了方舟编译器的理论基础。在这个理论基础上,方舟编译器团队基于 MAPLE IR 做了更复杂的优化和更广义的控制流分析。

2019 年 4 月份,华为发布方舟编译器(ArkCompiler),同时在 8 月底将其编译框架代码开源,并计划后续完整开源方舟编译器的所有代码。然而,开源后的方舟编译器受到了四面八方开发者的高度关注,面对现在开源出来的少量代码,很难让人相信这是一个多语言、跨平台、高效的编程环境。

于是,整个团队首次公开了方舟编译器的基础架构和源码分析。

2、方舟编译器源码分析

8 月 31 日,华为方舟编译器开源了编译器框架部分源码,包括编译器中间表示(IR,Intermediate Representation)和语言编译实现,同时搭配编译器其它二进制组件,实现 Java 程序到 aarch64 汇编指令的编译过程。

在华为的描述中,开发者可基于开源代码和二进制,编译构建出编译器工具链,尝试对 Java 程序进行编译。社区参与者可以通过框架源码学习方舟编译器的编译器中间表示(IR)及基本的中端编译框架,熟悉方舟编译器的架构思想,并参与诸如对编译器中端优化的贡献。方舟编译器是为支持多种编程语言、多种芯片平台的联合编译、运行而设计的统一编程平台,包含编译器、工具链、运行时等关键部件。

就目前可见的范围,整个方舟编译器的开源部分代码由 C、C 的头文件、源码和汇编代码组成,C 语言的头文件占了绝大部分,目前提供的代码一共有七万多行,注释大概有一万多行,还有很多空行,加起来大约有 10 万行代码,而其中的注释非常之少。每个文件的大小整体也不是很大,个别超过了 2000 多行,大部分在 1000 行以下。

从代码内容来看,主要是与中间代码相关的部分,当然也包括了 Phase、IPA,但实际里面主要是阶段性管理的辅助代码,真正相关的代码目前还没有呈现。huawei_secure_c 的文件中存放了大量关键代码,比如内存拷贝等关键函数。根据选取的几个测试用例,目前对 Java 1.6 及以上版本的支持都没有问题,从 Java 到 IR 的翻译还是比较顺畅,只不过在第三库版本支持上可能会有问题。

至于上文提到的中间代码,根据 MAPLE 的文档,主要有如下几个特点:

    尽可能保留源代码信息;

    高层次树状层次化结构;

    低层次与指令一一对应;

    可扩展——支持新的语言和控制结构。

方舟基础架构与 IR 中间表示

目前开源的方舟基础架构一部分是关于 Java/Kotlin 的编程语言实现,因为这两类语言强依赖虚拟机,方舟编译器去掉了虚拟机之后,补全了一些功能在里面;另一部分是后续优化和分析的基础支持,比如开源了 SSA 的表示。

方舟编译器架构师在近期的分享中表示,Maple IR 设计时基本考虑了三件事情:

1、IR 存在于三种不同的格式中:

Binary,主要用来做分发,或者是真正执行时需要考虑效率问题;

中间语言需要有可读性,因为程序员很关心代码的执行过程;

存在 In-memory 的过程,也就是组织中间语言在内存的存储。

2、分层设计,Maple 的整个想法来源于 Open64 的鼻祖 Fred Chow,而 Open64 当时的设计是五层结构。方舟编译器总结和借鉴了 Open64 的经验,形成了一个分层的设计,按需来选择不同层次。这样可以让高层语言快速回到原代码,大多数编译器都会支持这一功能,很多的应用场景都可用到。此外,高层的中间表示对实现接近原语言的优化会比较方便。比如,方舟编译器保留了较高层 Class 类型,这样做 TBAA 和 Devirtual 相对容易。

3、高层结构更接近原语言。原语言的代码最为精简,方舟编译器希望中间结构也能够更加精简,比如分发格式更小。同时,希望能够重用编译优化能力,当引入新语言时,能够尽量减少改动。分层之后引入新语言,可以只改高层,高层拓展后,底层所有优化保持不变。

在中间语言的部分,方舟编译器架构师表示可分为两部分看待:类型和操作符。

在类型上,Maple 编译器中有一个 Global tab 的表示,所有全局符号都保存在这里。第一项就是 type tab,这个的实现就是 MirType 的一个 vector。MirType 的定义基本上就只有这几项,首先要看类型到底是什么类型。其次,类型里面的 Primitive Type 是什么样子,比如说是一个 Int 或者更复杂的结构体。

基于最基础的 MirType,可以扩展出 Structure 结构。之后信息更加丰富,比如会有父类的一些 Field,还有 VTab、ITa 等。基于 MirStructType,可以扩展出高层结构,方舟编译器会保留 Class 信息,这部分目前来看对分析和优化的帮助非常大。

在操作符上,方舟编译器支持 Memory 的操作,也有结构化的操作符。除了支持传统调用,还支持很多 Java 特有的调用。

在内存管理上,方舟编译器目前是以 RC 为主,GC 为辅。开发者可能对 GC 比较熟悉,这里讲下对 RC 的一些支持。RC 是一个比较容易理解的事情,多一个引用就加一,少了就减一,思想比较简单。在真实应用中,方舟编译器加一的情况基本就四种:

一个对象引用了另一个对象,进行加一;

栈包括寄存器里的变量要去引用对象,再次加一;

静态或者全局变量多加一个引用的话,也要加一;

函数返回对象,也要加一。

减一的场景也比较简单,比如局部变量 Last Use 后,因为局部变量已经死掉,指向的原来对象要进行减一操作;如果某个变量被重新赋值,原来指向的堆对象也要进行减一操作。

在这种方式下,一个特别简单的函数可能要进行一系列加减操作,每次操作可能都要加锁,基本程序很难跑起来。于是,整个团队又开始从三个角度对此进行优化:

第一,减少插入,很多变量间的 Live Range 可能是重叠的,重叠后前面加一,后面减一的操作就可以不做了;如果实在没有办法避免插入,就看如何减少每一次操作的开销,方舟编译器有一个逃逸分析,最主要的结果是看变量会不会被多线程访问。如果变量的值被单线程访问,就不需要加锁,只需要加一或减一操作,然后保证不被提前释放就可以。

第二,RC 操作是比较麻烦的事情,方舟编译器现在提供 Annotation 的方法,Annotation 的效果应该是最好的,但对程序员要求较高,如果程序员加的不对,内存可能会出现泄漏。另外,方舟编译器也提供自学习的方法。

第三,方舟编译器以 RC 为主,GC 为辅。如果一些环没有被 RC 释放掉,可以从被 GC 释放掉的环里学到一些规则,把这些规则写成一个文件或者放到内存里,指导下一次运行时的内存释放。

如上图,绿色的部分已经完成,黄色的部分还在开发中,而蓝色的部分还在规划中,华为希望与社区进行共建。

接下来,方舟编译器团队会开放跨语言全程序优化能力。对 Android 而言,从 Java 到 C 或者从 C 到 Java 的调用,整个次数会非常多,而且每一次调用的开销也比较大。如果能够把这一部分做好,大概能够提高 10% 到 20% 的性能。

另外,整个团队还做了一些安全编译,比如把运行时错误移到编译时做,因为在运行时的状态下,Bug 很难查找,如果在编译时就对问题进行报警,这样对开发者比较友好。

3、生态是绕不过的难题

目前方舟编译器的代码托管在华为云与码云平台(gitee.com),遵守的开源协议是中国首个开源协议——木兰宽松许可证,这样做的目的也是为了规避其他协议潜在的开源风险。在未来走向开放治理以后,方舟编译器将按照所挂靠机构的模式来托管。开发者可通过代码托管平台参与社区贡献,包括文档贡献和代码贡献,同时也可在此平台上反馈相关问题和需求。

在生态构建方面,很多开发者都认为这是方舟编译器需要迈过的一道大坎。其实,做生态不一定只有开源这一条路径,苹果没有开源却依然有大批开发者愿意为其平台开发应用,鸿蒙 OS 的开源主管表示,华为之所以选择开源方舟编译器,一是真的希望得到广大开发者的帮助,和众多编译器领域优秀的学者和从业人员一起进步;二是希望获得广大开发者的信任。

但是现在,很多开发者都觉得难以参与,因为没有 Runtime,开放的源代码也非常少。华为方舟编译器架构师表示方舟编译器其实有一个 Runtime,用来实现各种与运行相关的信息,比如 Java 反射、JNI 调用、内存管理、内存回收机制等,但现在只有 6 万行代码,是一个非常轻量级,只提供必备内容的 Runtime。

目前开发者可以先在华为手机上运行 ,同时华为也希望社区可以一起通过开源的方式做一个简单的 Runtime。后续会按照计划尽快开放所有源代码,因为代码开源需要进行很多清理和整改,时间上希望各位开发者多些耐心。如果开发者希望参与社区构建,可以考虑以下几个角度:

共建方舟 IR。其实现在方舟 IR 的标准还没有完全定下来,处在逐渐发展的过程中,华为希望和大家一起把标准做得更好。这里面也有很多挑战性的工作,因为不同的高级语言有不同的特征,类型系统、内存管理机制、内存对象模型都可能不同,希望大家能够形成更好的标准,支持更多语言表达;

多语言前端,目前的编译器只做了 Java,C 还在内部开发中,其实还有更多语言,包括 JS,也希望社区中的广大开发者共同建设;

多芯片后端,华为内部只做了 ARM64 的后端,ARM32 还在规划中,但可能有一些厂家用 X86,开发者可以结合自己的芯片做一些后端开发用到自己的产品中;

对编译算法有兴趣的同学,可以在中端和后端做一些编译算法优化,包括数组越界检查消除、锁优化等,这可能对大家都有好处。

4、结束语

方舟编译器的愿景就是构建多语言、跨平台、高效的编程环境。面向未来,华为做了很多全场景智慧化场景的尝试,如何全场景下进行高效编程以及在整个 IR 层面,如何进行优化等都是极具挑战的任务,方舟编译器未来同样希望与硬件更好结合,而这些都需要更多开发者参与其中。

方舟编译器主页:

https://www.openarkcompiler.cn

官方主库:

https://code.opensource.huaweicloud.com/HarmonyOS/OpenArkCompiler/home

Gitee 镜像仓库:

https://gitee.com/harmonyos/OpenArkCompiler

如果没有Google这个靠山,Go 凭什么火?

整理 | 章雨铭 责编 | 屠敏

出品 | CSDN(ID:CSDNnews)

自从2009年开源以来,Go获得了越来越多开发者的喜爱,在最新的TIOBE编程语言排行榜中排名第14。开发者调查分析公司SlashData发布了2021年《开发者报告》显示,Go开发者数量的增长速度是Ruby的两倍。许多大公司比如Facebook、腾讯、百度都有项目使用Go语言,Docker和Kubernetes也都是由Go编写的,另外,Go语言还受到许多云创业公司的喜爱。

那么为什么Go如此受欢迎呢?Go的五位创始人在《Communications of the ACM》一书中揭晓了答案,其中表示,Go的成功之处在于它专注于软件项目设计的整体环境。一方面,Go的以开发为中心的理念让其社区得以蓬勃发展。另一方面,Go社区及其构建的技术最终使得Go成为现代云计算环境的重要组成部分。

(Tiobe Index排名)

Go的早期发展

Go是一种静态强类型、编译型语言,在语法上和C语言相近,但Go包含垃圾回收功能,可以自动释放变量不再使用的内存。另外,Go利用了新的多核处理器,在专用内核上运行垃圾回收,以降低对延迟的影响。

并发性是作为Go语言的核心功能提供的,而不是作为单独可选的库提供的。这很大程度上解释了为什么Go是这样建造的。

在Go的成长中吸取了很多谷歌的经验,并且有4000名活跃的开发者共享的庞大的多语言代码库,这些开发者认为需要有一种更好的方法来处理大规模负载。于是Go孕育而生——它是专门设计用于并发性以及为其提供一流的支持,不仅可以有效的处理多个任务,还能同时执行多个任务。

在Go诞生之前,工程师们一直使用着相对笨拙的语法和大小固定的线程堆栈,那时,支持并发的线程并不受欢迎,因为它们不仅难创建而且难以使用和管理。

而解决这个问题是创造Go的主要动机之一。

对开发者的关注贯穿于Go的开发

云服务的发展也为Go带来了更多的使用者。

另外Go相比于其他的语言,还具有一些明显的优势。Go创始人在文中提到,Go "消除了在C和C 程序中导致许多问题的未定义行为"。(例如,如果代码试图运行一些有风险的行为,如解读空指针或使用超出数组或分片界限的索引,Go会简单地抛出一个运行时异常并停止运行程序)。

但Go的创始者认为,Go受欢迎另有原因。Go在构建项目的早期工作中发挥了很大的作用,为软件开发的打包、依赖关系、构建测试、部署和其他的日常工作建立了基础。

这吸引了那些将软件包用在其生态系统的开发者。虽然最初的版本只支持在Linux和MacOS X上使用,但Go社区中热情的开发者们很快就为Go的编译器和库创建了Windows版本,并将它们移植到其他操作系统。

其创始人表示,对开发者的关注贯穿于Go的开发。比如Go中包含对安全通信协议SSL和TLS支持的高质量加密库,以及包括一个内置的HTTPS客户端和服务器(用于与其他系统在线交互)的标准库。

Go处理库的方式也对开发者大有助力:Go的编译器只导入必要的库以包含在其二进制文件中,这避免了为了确保包含一个必要的功能,而导入整个库。

另外,考虑到开发人员的需求,Go允许从其他领域轻松导入外部库(同时还有自动检查兼容版本的方法)。

Go在标准版本中还支持优化技术,如程序剖析,以及对测试功能的支持,如模糊处理。Go甚至有一个代码布局的惯例。(Go的gofmt工具将源代码解析成这种标准化的布局。)gofmt工具和其他内置的工具有助于使Go更容易建立从IDE插件和调试器,到框架和构建自动化的任何东西。Go的创造者认为,他们的语言是专门为鼓励创建工具和自动化而设计的,"因此,Go中有一个丰富的、不断扩展的、互操作的工具包"。

保持一致性

虽然Go的创造者们也承认,在Go最早的几年里,每个星期的发布中都会对进行修补和调整。用户在更新到新的Go版本时,往往不得不改变他们的程序。

不过2012年以来(随着Go第一版的正式发布),Go的更新就只对语言和标准库进行向后兼容的修改,这样程序在编译到较新的Go版本时可以继续运行而不发生变化。

虽然结果并不乐观,但是Go的工具有了极大的发展——更好的编译器,更强大的构建和测试工具以及更多的支持Go的开源工具。

"虽然大多数语言的设计都集中在语法、语义或类型的创新上,但Go却专注于软件开发过程本身。"

——Matt Weagle (@mweagle) 2022年5月11日

文章指出,Go的功能集能够避免开发人员的过度拓展。但是,同时也提到了这一惯例的例外情况,即Go确实增加了一个重要的新功能。两个月前,Go增加了参数化多态性,是 "为适应Go的其他部分而量身定做的..."

"在坚持一致性、完整性和社区原则的情况下做出如此大的语言改变,将是对这种方法的严峻考验"。

Go的创造者表示Go能够有今天的成就和发展,离不开Go社区的成千上万的开源贡献者们。正如Go的创始人所说:"我们感谢每一个帮助Go成就今天的人"。

参考资料:

https://thenewstack.io/what-made-golang-so-popular-the-languages-creators-look-back/

成就一亿技术人

免责声明:本文由用户上传,如有侵权请联系删除!