每日一题-Redis AOF日志重写

回复

数据库 peanut 回复了问题 1 人关注 1 个回复 209 次浏览 2020-11-07 10:18 来自相关话题

未来中国的芯片产业暗藏着哪些机会?

科技前沿 星物种 发表了文章 0 个评论 89 次浏览 2020-11-06 23:45 来自相关话题

一说芯片,大家就会想到CPU。提到CPU,我们知道得最多的是两种,一种是英特尔、AMD使用的x86架构,一种是ARM架构。其实,除了这两个之外,还有那些做得不是很成功的CPU架构,我相信你绝大部分没听说过。它们有MIPS架构、Sparc架构、Power架 ...查看全部

一说芯片,大家就会想到CPU。提到CPU,我们知道得最多的是两种,一种是英特尔、AMD使用的x86架构,一种是ARM架构。其实,除了这两个之外,还有那些做得不是很成功的CPU架构,我相信你绝大部分没听说过。它们有MIPS架构、Sparc架构、Power架构和Alpha架构,还有最新出现在人们视线的RISC-V。


除了最知名的x86和ARM这两种架构,其它的架构路线可以说非常坎坷。


MIPS架构最早是由80年代初斯坦福大学研究出来的,是最早商业应用的芯片之一,但规模远不如x86和ARM。


Sparc架构是由Sun公司设计的,在微机时代 ,Sun是在硅谷唯一可以和IBM比肩的巨头,但在2010年被甲骨文收购,Sparc架构也渐渐淡出人们视线。


Power架构最早是IBM开发的,但IBM的战略是自己做系统集成,面对Intel的x86架构联合Windows联盟的竞争,IBM最后败下阵来,就没有投入更多精力继续做开发了。


Alpha架构是DEC公司开发的,后来DEC被惠普公司收购,而惠普公司产品线都集中在x86技术路线上,Alpha架构卖给了中国无锡的江南计算所,我们后面还会提到。

还有最新的RISC-V架构,据说很多国内公司包括小米、华为、阿里都砸了重金投入,但目前还没有构建出一个完整的生态出来。

接下来我们展开讲讲,采用这些不同架构技术路线的公司,哪些芯片公司做起来了,哪些公司未来有可能会失败。


一、中国的第一阶段


Mips架构



MIPS架构处理器最早是由80年代初斯坦福大学研究出来的,国内使用MIPS架构处理器的代表是龙芯中科。龙芯中科的背景来自中国科学院计算所,最早用MIPS架构搭配Linux系统,打造国产PC。龙芯中科的董事长胡伟武是中国科学院计算技术研究所研究员、总工程师,在国内的CPU研发领域是相对做得还算不错的。

另一家采用MIPS架构的是北京君正,研发的领域主要是物联网设备,不需要很强的CPU性能,而是强调价格便宜、功耗低。物联网这个领域正在兴起,参与企业非常多,所以也容易在这个市场里分到一块蛋糕。


Power架构
刚才提到的IBM研发的Power架构,2016年一家国内企业中昊宏芯从IBM买到了POWER架构的永久授权,但是研发过程并不顺利,至今都没有看到太多的应用。

Alpha架构
无锡江南计算所买下了Alpha架构所有设计资料,开发了国产Alpha处理器,此前多次夺得超算排名第一的“神威·太湖之光”,就是用的这种处理器。


其实相比移动计算,超算并不需要太先进的芯片。原因很简单,移动计算的散热、能耗要求非常苛刻,而服务器的空间很大,对体积没有太大的要求,对散热、能耗更没有太大的限制,能耗大点没关系,散热可以有单独的采用液冷技术的机柜设备。简单说就是砸巨资投入,把大量的芯片和相关设备堆砌起来,从而实现强大的算力。


另外,申威处理器也是目前唯一的Alpha架构处理器产品了,并不具备大规模应用的前景,我们普通人更是基本接触不到了。



x86架构
然后说到x86架构了。中国企业发展x86,比较难的是授权,因为x86架构一直在Intel和AMD手里。除了Intel和AMD以外,第三家拥有X86授权的公司,是台湾威盛,上海兆芯用2.57亿美元从威盛那儿买到了x86授权。上海兆芯是上海市政府控股的基金,为了生产中国的芯片,于是和台湾威盛合资,上海政府控股80%,就是冲着芯片去的。


但是这个x86授权是很残缺的,是威盛与Intel的官司之争中拿到的,授权期限在2018年4月就过期了,以后研发新的架构只能靠兆芯自己了,所以兆芯的位置很尴尬。


另外,虽然上海兆芯也推出了产品在市场上销售了,但因为没有大规模销售,没法分摊研发成本,性价比还是非常低的。


另一家拿到x86架构的是天津海光,是从AMD那儿拿到的授权,而不是Intel。为了绕开Intel,玩了一个什么游戏呢?AMD和海光先成立合资公司A,AMD是大股东,左手授权给右手。随后AMD和海光成立合资公司B,这家公司海光是大股东,然后合资公司B从合资公司A那儿拿到了授权,这样就绕开了Intel。


不过这样的做法海光处理器是十分受限的,被规定只能在中国境内销售。海光是很被动的,产品能否长期生产销售主要取决于AMD,如果AMD不同意,那海光处理器就不能继续生产了。所以这样的合作只能防住Intel,但是防不住美国封锁。


二、中国的第二阶段

上面提到的芯片架构,中国的国产化都做得不算成功,但是到ARM架构上我们能看到一些曙光了。华为海思、飞腾、展讯都是做ARM相对比较不错的。华为海思的处理器主要应用于移动端产品,手机和智能家居产品都有应用。天津飞腾最早用Sparc处理器,也就是刚才提到的Sun公司开发的,但是Sun被甲骨文收购以后,飞腾就转向ARM架构了,主要面向国家安全市场,为军队、政府服务。


这里特地要表扬的是展讯,这是一家不错的国内的采用ARM架构的公司。展讯的手机芯片主要用于低端手机,只支持GSM和GPRS两种网络制式,市场主要面向非洲、东南亚等低收入海外市场。同时展讯也有基带芯片,目前有5G基带芯片的厂商只有五家:华为、联发科、高通、三星,最后一家就是展讯。这也是中国企业未来可能去实践的一条芯片破局之路,那就是和行业深度结合。通讯就是一个很重要的行业,展讯也是从通讯行业做起来的。

三、中国的第三阶段

芯片的发展速度在加快,真正的机会在于第三阶段,那就是人工智能和云的时代。寒武纪在科研方面非常领先,陈云霁2014年就设计出了用汉语拼音命名的DianNao人工智能芯片设计架构,被认为是世界第一,要比谷歌的TPU都要早了两年。而且之前一直和他有紧密合作的法国的Olivier Temam教授14年被挖到了谷歌,谷歌研究TPU的论文里也多次引用陈云霁的论文,应该说TPU的设计里借鉴了陈云霁的思想。


但是寒武纪之所以也比较难,那是因为我们的生态还没有搭建起来。我们看见哪一个是好的芯片企业,我就拿大钱给他,结果芯片企业的心态就是:我不能合作,如果我扶植一帮合作伙伴起来,这个补贴的钱就分流了,而我越说自己什么都干就越拿更多的钱。最终就导致了“竖井式结构”:比如华为抛弃了寒武纪,从芯片设计到生产、应用全都自己做,阿里巴巴本来是需求方,做云计算需要大量芯片,结果也是从研发到生产大包大揽。这跟全世界的发展趋势是背道而驰的。


四、总结

前面我们讲了那么多芯片,你会发现,有不少今天不那么普及的芯片架构,都是一些边边角角的不重要的技术领域。一家芯片企业如果没有选中未来的主流技术,很有可能会被淘汰掉,因为你的做法不是未来有最大机会的方向,这家企业再怎么优秀都没有用。


芯片的发展是两条路线,一条是通用芯片,覆盖所有人。这条路要跟上时代,现在的机会就是人工智能+云计算,这方面的赢家是NVIDIA。中国曾经本来有机会,但是很可惜没有把握住。但是另一条路是我们未来可以把握住的,那就是与行业深度结合的专用芯片。


所谓专用芯片,就是在行业里深挖,借助自己的行业优势来培养自己的芯片优势。像欧洲依托行业配置出了英飞凌、意法半导体、恩智浦这样的芯片公司,在汽车电子、工业制造、传感器有着很深的应用。而中国未来的行业机会,我认为有三个:无线通讯、无人驾驶和物联网


在无线通讯领域,已经有比较优秀的公司,就是刚才介绍的做5G基带芯片的展讯。


在无人驾驶领域,因为未来电动车都会上自动驾驶,以后越来越多会出现封闭路面的自动驾驶、货运车、还有小型的送货车,自动驾驶的芯片的需求越来越大。这方面我觉得有机会的是地平线。我开玩笑说,高端是负责管吆喝的,低端是负责赚钱的,地平线的芯片虽然没那么高端,但是性价比更高,接地气的战略可能会有更大的优势。


最后,物联网领域给我们留下了一个悬念。这个领域的差异化很大,比如未来这个领域需要很多相对低端的芯片,性能参差不齐,也需要所谓叫模拟转数字的芯片,大量的模拟芯片会有应用空间。这个领域还有一定的不确定性,中国有可能会有胜出的机会。


对于中国芯片企业的发展,我的建议是要在正确的方向上两条腿走路:首先是持续的研发投入,然后是不断巩固生态


芯片战争不是一个瞬间能决定胜负的东西,像Intel和AMD打了这么多年,因为科技领域的用户没有品牌忠诚度,比的是性能好坏而不是品牌,如果Intel过去三十年不努力做研发,“Intel Inside”的标志就没有那么大的作用。所以持续研发投入是个必要条件。


另一方面来讲,凭什么能在研发上有持续投入?因为你在市场上能够持续获得高额回报,而巩固市场的核心是要巩固生态,你要能够和一堆的合作伙伴一起去开发更多的应用,这个市场才能繁荣起来。这是中国的短板,也是未来四十年中国必须要面对和解决的问题。


分享阅读原文:http://m6z.cn/6d7clf

Prometheus配置文件热加载

智慧运维 push 发表了文章 0 个评论 89 次浏览 2020-11-05 16:36 来自相关话题

Promtheus的TSDB时序数据库在存储了大量的数据后,每次重启Prometheus进程的时间会越来越慢, 而且日常运维工作中会经常调整Prometheus的配置文件信息,比如一些静态配置,实际上Prometheus提供了在运行时热加载配置信息的功能 ...查看全部

Promtheus的TSDB时序数据库在存储了大量的数据后,每次重启Prometheus进程的时间会越来越慢, 而且日常运维工作中会经常调整Prometheus的配置文件信息,比如一些静态配置,实际上Prometheus提供了在运行时热加载配置信息的功能,在这里介绍一下。


Prometheus配置热加载提供了2种方法:


  1. kill -HUP pid 发送SIGHUP信号方法
  2. 通过Prometheus服务API接口,发送发送一个POST请求到/-/reload

Tips: 从 Prometheus2.0 开始,热加载功能是默认关闭的,如需开启,需要在启动 Prometheus 的时候,添加 --web.enable-lifecycle 参数。



我个人更倾向于采用curl -XPOST http://localhost:9090/-/reload 的方式,因为每次reload过后, pid会改变,使用kill方式需要找到当前进程号。


如果配置热加载成功,Prometheus会打印出下面的log:


... msg="Loading configuration file" filename=prometheus.yml ...

下面我们来看看这两种方式内部实现原理。


第一种方法: 通过 kill 命令的 HUP (hang up) 参数实现
首先Prometheus在 cmd/promethteus/main.go 中实现了对进程系统调用监听,如果收到syscall.SIGHUP信号,将执行reloadConfig函数。


代码类似如下:


{
// Reload handler.

// Make sure that sighup handler is registered with a redirect to the channel before the potentially
// long and synchronous tsdb init.
hup := make(chan os.Signal, 1)
signal.Notify(hup, syscall.SIGHUP)
cancel := make(chan struct{})
g.Add(
func() error {
<-reloadReady.C

for {
select {
case <-hup:
if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
level.Error(logger).Log("msg", "Error reloading config", "err", err)
}
case rc := <-webHandler.Reload():
if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
level.Error(logger).Log("msg", "Error reloading config", "err", err)
rc <- err
} else {
rc <- nil
}
case <-cancel:
return nil
}
}

},
func(err error) {
// Wait for any in-progress reloads to complete to avoid
// reloading things after they have been shutdown.
cancel <- struct{}{}
},
)
}

第二种:通过 web 模块的 /-/reload请求实现:


首先 Prometheus 在 web(web/web.go) 模块中注册了一个 POST 的 http 请求 /-/reload, 它的 handler 是 web.reload 函数,该函数主要向 web.reloadCh chan 里面发送一个 error。


其次在Prometheus 的cmd/promethteus/main.go中有个单独的 goroutine 来监听web.reloadCh,当接受到新值的时候会执行 reloadConfig 函数。


func() error {
<-reloadReady.C

for {
select {
case <-hup:
if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
level.Error(logger).Log("msg", "Error reloading config", "err", err)
}
case rc := <-webHandler.Reload():
if err := reloadConfig(cfg.configFile, logger, noStepSubqueryInterval, reloaders...); err != nil {
level.Error(logger).Log("msg", "Error reloading config", "err", err)
rc <- err
} else {
rc <- nil
}
case <-cancel:
return nil
}
}

},

Prometheus内部提供了成熟的hot reload方案,这大大方便配置文件的修改和重新加载,在Prometheus生态中,很多Exporter也采用类似约定的实现方式。

每日一题-redis数据持久化

数据库 peanut 回复了问题 2 人关注 2 个回复 117 次浏览 2020-11-05 14:36 来自相关话题

每日一题-Redis 为什么那么快?

编程艺术 空心菜 回复了问题 3 人关注 2 个回复 110 次浏览 2020-11-05 10:34 来自相关话题

企业不同时期的运维规划

智慧运维 OS小编 发表了文章 0 个评论 87 次浏览 2020-11-02 22:32 来自相关话题

企业创业期企业创业初期,人员少,业务流量不大,服务器数量相对较少,系统复杂度不高。对于日常的业务管理操作,因人员少,吼一声,大家就登录服务器进行手工操作,属于各自为战,每个人都有自己的操作方式,权限管理混乱、编写代码的风格各异,缺少必要 ...查看全部

企业创业期

企业创业初期,人员少,业务流量不大,服务器数量相对较少,系统复杂度不高。对于日常的业务管理操作,因人员少,吼一声,大家就登录服务器进行手工操作,属于各自为战,每个人都有自己的操作方式,权限管理混乱、编写代码的风格各异,缺少必要的操作标准、流程机制,比如业务目录环境都是各式各样的。在这个阶段建议建立如下规范:


  • 统一权限管理:应用程序、操作员、管理员权限分离。
  • 制定完善的操作流程:先开发环境验证、测试环境验证、预生产环境、生产环境的基础操作流程,最小操作权限、最小化的目录权限为准则。
  • 制定代码发布流程和机制:以开发环境、测试环境发布为先,在预生产环境、生产环境发布制定相应的审核。
  • 制定代码编写规范:制定排版、注释、标识命名、异常处理等相关规范,避免出现个性化的代码。
  • 使用云商自有监控做基础监控,主要是cpu、内存、网络等。
  • 强化系统、业务基线安全。


企业高速发展期

在企业发展期,拿到融资后,业务快速发展,随着服务器规模、系统复杂度的增加,全人工的操作方式已经不能满足业务的快速发展需要。因此,运维人员逐渐开始使用批量化的操作工具,针对不同操作类型出现了不同的脚本程序。


但各团队都有自己的工具,每次操作需求发生变化时都需要调整工具。这主要是因为对于环境、操作的规范不够,导致可程序化处理能力较弱。此时,虽然效率提升了一部分,但很快又遇到了瓶颈。在这个阶段建议建立如下规范:


  • 制定运维相关脚本的编写标准:如统一相关备份空间、相关备份执行计划,制定相关脚本的执行人员、执行权限、执行时间。
  • 统一同类工具的使用:如数据连接工具、备份工具、数据同步工具等。
  • 确认相关的操作人,减少或者避免开发和测试在服务器上的相关操作。
  • 部署监控平台进一步的监管数据库、进程、日志等。
  • 使用第三方应用性能管理对应用性能做应用分析和优化。


企业稳定发展时期

在企业稳定期,在这个阶段,对于运维效率和误操作率有了更高的要求,我们决定开始建设运维平台,通过平台承载标准、流程,进而解放人力和提高质量。
这个时候对服务的变更动作进行了抽象,形成了操作方法、服务目录环境、服务运行方式等统一的标准。通过平台来约束操作流程。

在平台中强制需要运维人员填写相应的检查项,然后才可以继续执行后续的部署动作。在这个阶段建议建立如下运维平台:


  • 统一运维操作和管理平台:操作管理、权限管理、资源。
  • 统一日志平台:统一日志收集标准、日志收集接口,查询方式,查询授权。
  • 统一监控平台:强化监控,从系统、数据库、缓存、中间件、接口、业务性能等。
  • 统一发布平台:细化发布项目、发布权限、发布审核、回滚、备份等。
  • 加强安全防护:上线前做安全加固、安全评估、渗透测试等。
  • 统一开发规范:统一接口、数据库、配置文件等规范。


企业集团化、规模化发展时期

更大规模的服务数量、更复杂的服务关联关系、各个运维平台的林立,原有的将批量操作转化成平台操作的方式已经不再适合,需要对服务变更进行更高一层的抽象。比如智能告警、故障自愈、运营辅助决策等。


这个阶段需要大量的运维数据支持,做相应的数据分析、测试,才能使用,不然因误报或错误的故障自愈决策造成大规模的故障。


分享阅读原文: http://m6z.cn/6sGPLO

四大CPU体系架构介绍

科技前沿 koyo 发表了文章 0 个评论 105 次浏览 2020-11-02 00:54 来自相关话题

RISC(reduced instruction set computer,精简指令集计算机) 是一种执行较少类型计算机指令的微处理器,起源于80年代的MIPS主机(即RISC机),RISC机中采用的微 ...查看全部

RISC(reduced instruction set computer,精简指令集计算机) 是一种执行较少类型计算机指令的微处理器,起源于80年代的MIPS主机(即RISC机),RISC机中采用的微处理器统称RISC处理器。这样一来,它能够以更快的速度执行操作(每秒执行更多百万条指令,即MIPS)。因为计算机执行每个指令类型都需要额外的晶体管和电路元件,计算机指令集越大就会使微处理器更复杂,执行操作也会更慢。 


性能特点一:由于指令集简化后,流水线以及常用指令均可用硬件执行;


性能特点二:采用大量的寄存器,使大部分指令操作都在寄存器之间进行,提高了处理速度;


性能特点三:采用缓存—主机—外存三级存储结构,使取数与存数指令分开执行,使处理器可以完成尽可能多的工作,且不因从存储器存取信息而放慢处理速度。


RISC平台的发展已经有长达几十年的历史了。其最早诞生于80年代的MIPS主机,随着技术的不断发展,RISC平台的应用领域逐步扩展,小到手机, 大到工控设备都可以见到他的身影。随着RISC平台的发展还诞生了与之相适应的应用软件,最终组成了现在人们较为熟知的嵌入式系统。当前桌面级消费者最为 熟知的Atom凌动平台便是嵌入式代表之一。但是与今天我们所要谈到的两位主角相比,intel的凌动平台就是小巫见大巫了。这正是诞生了RISC平台的 MIPS和当前RISC领域中最为强大的ARM。


MIPS是世界上很流行的一种RISC处理器。MIPS的意思”无内部互锁流水级的微处理器”(Microprocessor without interlocked piped stages),其机制是尽量利用软件办法避免流水线中的数据相关问题。它最早是在80年代初期由斯坦福(Stanford)大学Hennessy教授领导的研究小组研制出来的。MIPS公司的R系列就是在此基础上开发的RISC工业产品的微处理器。这些系列产品为很多计算机公司采用构成各种工作站和计算机系统。MIPS技术公司是美国著名的芯片设计公司,它采用精简指令系统计算结构(RISC)来设计芯片。和英特尔采用的复杂指令系统计算结构(CISC)相比,RISC具有设计更简单、设计周期更短等优点,并可以应用更多先进的技术,开发更快的下一代处理器。MIPS是出现最早的商业RISC架构芯片之一,新的架构集成了所有原来MIPS指令集,并增加了许多更强大的功能。


MIPS处理器是八十年代中期RISC CPU设计的一大热点。MIPS是卖的最好的RISC CPU,可以从任何地方,如Sony,Nintendo的游戏机,Cisco的路由器和SGI超级计算机,看见MIPS产品在销售。目前随着RISC体系结构遭到x86芯片的竞争,MIPS有可能是起初RISC CPU设计中唯一的一个在本世纪盈利的。和英特尔相比,MIPS的授权费用比较低,也就为除英特尔外的大多数芯片厂商所采用。MIPS的系统结构及设计理念比较先进,其指令系统经过通用处理器指令体系MIPS I、MIPS II、MIPS III、MIPS IV到MIPS V,嵌入式指令体系MIPS16、MIPS32到MIPS64的发展已经十分成熟。在设计理念上MIPS强调软硬件协同提高性能,同时简化硬件设计。


中国龙芯2和前代产品采用的都是64位MIPS指令架构,它与大家平常所知道的X86指令架构互不兼容,MIPS指令架构由MIPS公司所创,属于RISC体系。过去,MIPS架构的产品多见于工作站领域,索尼PS2游戏机所用的”Emotion Engine”也采用MIPS指令,这些MIPS处理器的性能都非常强劲,而龙芯2也属于这个阵营,在软件方面与上述产品完全兼容。普通用户关注MIPS主要还是因为我国所谓的”龙芯”。龙芯一开始抄袭MIPS,后来购买到了授权。倒也并非龙芯不想发展X86架构的桌面CPU市场或者ARM架构的移动设备市场,是因为这两家的授权太过于苛刻。X86的授权Intel已然不可能再授权。ARM是一家芯片设计公司,只能给出使用授权,不会同意让龙芯自行设计。只有MIPS才可行,MIPS的授权说白了就是随便抄随便改。很多龙芯的支持者提出了MIPS在理论上有诸多的领先,但不要忘了ARM是一家商业公司,市场占有率高,竞争意识也非常强。几乎所有的智能手机都是ARM架构,就是最有力的证明。


从某些方面来看,MIPS和ARM非常相似,都是采用精简指令集,都是针对低功耗应用设计,而且都是采用第三方授权方式生产;但实际上两者也有几大的不同,学院派的MIPS允许第三方对CPU架构进行大幅修改,而ARM只允许全球极少的几家半导体公司修改CPU架构(包括高通、苹果、NVIDIA和三星,全是半导体大拿),其他生产ARM芯片的公司都是直接采用ARM公版设计,而不能做任何修改(例如华为海思)。ARM的这项策略显然很适合商业推广,对第三方公司的技术要求也有所降低,开发的周期也会大大缩短,只需要照着ARM公版的CPU和GPU架构找芯片代工厂下单、流片、生产即可。


其中ARM/MIPS/PowerPC均是基于精简指令集机器处理器的架构;X86则是基于复杂指令集的架构,Atom是x86或者是x86指令集的精简版。


根据各种新闻,Android在支持各种处理器的现状:


ARM+Android最早发展、完善的支持,主要在手机市场、上网本、智能等市场;
X86+Android有比较完善的发展。有atom+Android的上网本,且支持Atom+Android和 Atom+Window7双系统;
MIPS+Android目前在移植、完善过程中;
Powpc+Android目前在移植、完善过程中。

当今处理器一共有三个最强大的架构,其中之一是以intel和AMD为代表的x86架构,另外一个是手机,平板处理器所使用的ARM架构,最后一个便是我国龙芯处理器所选择的MIPS架构。这三大处理器架构中,x86和ARM是商业化进程最为优秀的两大架构。也正是因为这两大架构的商业化进程太为出色,所以我国的龙芯处理器才被很多人批判为最严重的选择性失误。龙芯处理器的架构选择并没有错误,相反的如果龙芯要想得到更好的发展,选择MIPS才是最为正确的道路。x86架构的拥有者intel可以算作是技术合作上最抠门儿的一位,在推出x86架构之后,intel就只将这一架构授权给过AMD和VIA等几个芯片公司。而在VIA退出x86架构处理器竞争之后,intel便不再给任何公司x86架构授权。所以从x86架构上入手,龙芯处理器显然是行不通的。 intel的x86架构行不通,那么ARM架构是否就能行得通呢?答案当然也是否定的。


ARM

ARM架构,过去称作进阶精简指令集机器(Advanced RISC Machine,更早称作:Acorn
RISC Machine),是一个32位精简指令集(RISC)处理器架构,其广泛地使用在许多嵌入式系统设计。由于节能的特点,ARM处理器非常适用于行动通讯领域,符合其主要设计目标为低耗电的特性。

在今日,ARM家族占了所有32位嵌入式处理器75%的比例,使它成为占全世界最多数的32位架构之一。ARM处理器可以在很多消费性电子产品上看到,从可携式装置(PDA、移动电话、多媒体播放器、掌上型电子游戏,和计算机)到电脑外设(硬盘、桌上型路由器)甚至在导弹的弹载计算机等军用设施中都有他的存在。在此还有一些基于ARM设计的派生产品,重要产品还包括Marvell的XScale架构和德州仪器的OMAP系列。


优势:价格低;能耗低;


ARM授权方式:ARM公司本身并不靠自有的设计来制造或出售 CPU,而是将处理器架构授权给有兴趣的厂家。ARM提供了多样的授权条款,包括售价与散播性等项目。对于授权方来说,ARM提供了 ARM内核的整合硬件叙述,包含完整的软件开发工具(编译器、debugger、SDK),以及针对内含 ARM CPU 硅芯片的销售权。对于无晶圆厂的授权方来说,其希望能将 ARM内核整合到他们自行研发的芯片设计中,通常就仅针对取得一份生产就绪的智财核心技术(IP Core)认证。对这些客户来说,ARM会释出所选的 ARM核心的闸极电路图,连同抽象模拟模型和测试程式,以协助设计整合和验证。需求更多的客户,包括整合元件制造商(IDM)和晶圆厂家,就选择可合成的RTL(暂存器转移层级,如 Verilog)形式来取得处理器的智财权(IP)。借着可整合的 RTL,客户就有能力能进行架构上的最佳化与加强。这个方式能让设计者完成额外的设计目标(如高震荡频率、低能量耗损、指令集延伸等)而不会受限于无法更动的电路图。虽然ARM 并不授予授权方再次出售 ARM架构本身,但授权方可以任意地出售制品(如芯片元件、评估板、完整系统等)。商用晶圆厂是特殊例子,因为他们不仅授予能出售包含 ARM内核的硅晶成品,对其它客户来讲,他们通常也保留重制 ARM内核的权利。


生产厂商:TI(德州仪器)/Samsung(三星)/Freescale(飞思卡尔)/Marvell(马维尔)/Nvidia(英伟达)


ARM公司是一家非常优秀的芯片设计公司,但自身并不生产处理器,而是将自身的设计licensing卖给需要处理器的公司,而后交给他们生产或者是找人代工。也许有人要问了,既然ARM向外卖出架构设计,那么为何龙芯不去选择ARM架构呢?其实不然,ARM之所以能够发展成为一家非常成功的商业性公司,靠的就是芯片的架构设计,倘若架构设计被别人夺走了,那么自己就丢掉了赖以生存的饭碗。所以ARM虽然对外进行licensing授权,却不允许购买者进行任何对ARM架构有更改的设计。倘若个更改了设计,那么这便违反了合作协定,ARM便有权撤回licensing授权。我国的龙芯要是选择了ARM架构的话,那么基本上也就被捆住了脚步,无法发展出属于自己的高性能处理器了。


考虑到市场发展的问题ARM也对外妥协过。目前高通,苹果和NVIDIA这三家公司便是ARM体系中较为特殊的几个。因为这三家公司在芯片设计领域的特殊地位,ARM为了能够拉拢他们站立在自己的阵营中,对这三家公司开出了特别通行证。在其他芯片公司只能使用 licensing去生产芯片的时候,高通,苹果和NVIDIA却能够自行设计基于ARM架构的处理器。也正是拉拢到了高通,苹果和NVIDIA,才使得ARM拥有了更多的支持者。但即便这样,我们也不得不佩服ARM的老狐狸作风,在给出架构授权后,ARM依然会通过升级下一代架构为由让高通,苹果和 NVIDIA再掏一回钱购买架构授权。这样ARM就可以再赚一把。


x86系列或Atom处理器

x86或80x86是Intel首先开发制造的一种微处理器体系结构的泛称。x86架构是重要地可变指令长度的CISC(复杂指令集电脑,Complex
Instruction Set Computer)。

Intel Atom(中文:凌动,开发代号:Silverthorne)是Intel的一个超低电压处理器系列。处理器采用45纳米工艺制造,集成4700万个晶体管。L2缓存为512KB,支持SSE3指令集,和VT虚拟化技术(部份型号)。


现时,Atom处理器系列有6个型号,全部都是属于Z500系列。它们分别是Z500、Z510、Z520、Z530、Z540和Z550。最低端的Z500内核频率是800MHz,FSB则是400MHz。而最高速的Z550,内核频率则有2.0GHz,FSB则是533MHz。从Z520开始,所有的处理器都支持超线程技术,但只增加了不到10%的耗电。双内核版本为N系列,依然采用945GC芯片组。双内核版本仍会支持超线程技术,所以系统会显示出有4个逻辑处理器。这个版本的两个内核并非采用本地设计,只是简单的将两个单内核封装起来。


MIPS系列

MIPS是世界上很流行的一种RISC处理器。MIPS的意思是“无内部互锁流水级的微处理器”(Microprocessor without interlockedpipedstages),其机制是尽量利用软件办法避免流水线中的数据相关问题。它最早是在80年代初期由斯坦福(Stanford)大学Hennessy教授领导的研究小组研制出来的。MIPS公司的R系列就是在此基础上开发的RISC工业产品的微处理器。这些系列产品为很多计算机公司采用构成各种工作站和计算机系统。


MIPS技术公司是美国著名的芯片设计公司,它采用精简指令系统计算结构(RISC)来设计芯片。和英特尔采用的复杂指令系统计算结构(CISC)相比,RISC具有设计更简单、设计周期更短等优点,并可以应用更多先进的技术,开发更快的下一代处理器。MIPS是出现最早的商业RISC架构芯片之一,新的架构集成了所有原来MIPS指令集,并增加了许多更强大的功能。MIPS自己只进行CPU的设计,之后把设计方案授权给客户,使得客户能够制造出高性能的CPU。


1984年,MIPS计算机公司成立,开始设计RISC处理器;
1986年推出R2000处理器。
1992年,SGI收购了MIPS计算机公司。
1988年推R3000处理器。
1991年推出第一款64位商用微处器R4000;之后又陆续推出R8000(于1994年)、R10000(于1996年)和R12000(于1997年)等型号。
1998年,MIPS脱离SGI,成为MIPS技术公司;随后,MIPS公司的战略发生变化,把重点放在嵌入式系统;1998年-MIPS科技股票在美国纳斯达克股票交易所公开上市。
1999年,MIPS公司发布MIPS32和MIPS64架构标准,为未来MIPS处理器的开发奠定了基础。新的架构集成了所有原来NIPS指令集,并且增加了许多更强大的功能。MIPS公司陆续开发了高性能、低功耗的32位处理器内核(core)MIPS324Kc与高性能64位处理器内核MIPS645Kc。
2000年,MIPS公司发布了针对MIPS32 4Kc的版本以及64位MIPS 64 20Kc处理器内核。

2007年8月16日-MIPS科技宣布,中科院计算机研究所的龙芯中央处理器获得其处理器IP的全部专利和总线、指令集授权。
2007年12月20日-MIPS科技宣布,扬智科技已取得其针对先进多媒体所设计的可定制化系统单芯片(SoC)核心“MIPS32 24KEcPro”授权。

…..


MIPS和ARM虽然都是对外进行架构授权的公司,但意义完全不同。ARM对外出售的是设计方案授权 (licensing),与ARM的商业化相比,MIPS倒像是学院派的公司。MIPS的架构授权,并不限制任何对MIPS架构的更改。换句话说,就是 MIPS公司给授权者一张白纸,而白纸上仅仅写着一行字,MIPS公司同意你设计生产MIPS架构处理器,至于你设计成什么样,性能有多高,经过多少代更改,MIPS一概不管,只要你不把架构彻底改变就行了。与ARM相比,MIPS是一个完全开放的架构,对龙芯未来的发展没有任何的限制,这与intel给 AMD x86架构授权,而不是给设计图纸的道理是完全一样的。在加上MIPS本身经过几十年的发展,已经拥有了众多的应用软件,综合考虑来看,MIPS是最为适合龙芯处理器发展的架构选择。RISC平台是诞生于MIPS早先产品的,也正是RISC平台的诞生,才最终发展成为了我们现在的智能手机与平板机这样强大的产品。然而作为RISC系统的创始人,MIPS的商业化发展并非一帆风顺,也许是受公司前身是大学科学实验室的影响。公司高层对商业化发展嗤之以鼻, 这才令本身技术要落后于MIPS的ARM得到了发展时机。


PowerPC系列

PowerPC是一种精简指令集(RISC)架构的中央处理器(CPU),其基本的设计源自IBM(国际商用机器公司)的IBMPowerPC601 微处理器POWER(PerformanceOptimized With Enhanced RISC;《IBM Connect电子报》2007年8月号译为“增强RISC性能优化”)架构。


二十世纪九十年代,IBM(国际商用机器公司)、Apple(苹果公司)和Motorola(摩托罗拉)公司开发PowerPC芯片成功,并制造出基于PowerPC的多处理器计算机。


PowerPC架构的特点是可伸缩性好、方便灵活


PowerPC处理器有广泛的实现范围,包括从诸如 Power4那样的高端服务器CPU到嵌入式CPU市场(任天堂Gamecube使用了 PowerPC)。PowerPC处理器有非常强的嵌入式表现,因为它具有优异的性能、较低的能量损耗以及较低的散热量。除了象串行和以太网控制器那样的集成 I/O,该嵌入式处理器与“台式机”CPU存在非常显著的区别。

Pyhton列表去重方法总结

编程艺术 Ansible 发表了文章 0 个评论 81 次浏览 2020-11-02 00:22 来自相关话题

Python列表去重在Python应用编程中,是一种非常常见的应用技巧,有些场景下需要统计出来的列表中去重,避免重复统计。 1. 通过字典去重#!/usr/bin/env python3 ...查看全部

Python列表去重在Python应用编程中,是一种非常常见的应用技巧,有些场景下需要统计出来的列表中去重,避免重复统计。


1. 通过字典去重

#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
jobs = {}.fromkeys(job).keys()
print(list(jobs))

结果:


['Sale', 'Dev', 'OPS', 'Presale', 'Test']

解释:


Python 字典 fromkeys() 函数用于创建一个新字典,以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值。


语法:


dict.fromkeys(seq[, value])
  • seq - 字典键值列表。
  • value - 可选参数, 设置键序列(seq)的值。

该方法返回一个新字典, .keys 函数以列表返回一个字典所有的键。



2. 通过集合去重

大家都知道在Python数据结构中集合是天生去重的,所以我们可以利用这一特性来达到列表去重的效果。


格式: list(set(mylist))


#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
jobs = list(set(job))

由于采用集合,会导致原有的列表排序发生变化,此时可通过如下方法,保持列表原有顺序:


#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
jobs = list(set(job))
jobs.sort(key=job.index)


3. 使用itertools模块

#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy
import itertools

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
job.sort()

job_group = itertools.groupby(job)
jobs = []
for k, g in job_group:
jobs.append(k)
print(jobs)

groupby 根据key(v)值分组的迭代器, 将key函数作用于原循环器的各个元素。根据key函数结果,将拥有相同函数结果的元素分到一个新的循环器。每个新的循环器以函数返回结果为标签。



4. 通过列表推导式去重

#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']

jobs = []
[ jobs.append(i) for i in job if i not in jobs]

通过列表推导式,判断在不在新列表中的元素则添加到新列表中。



5. 利用lambda匿名函数和 reduce 函数处理

#!/usr/bin/env python3
# _*_coding:utf-8_*_
# Description: List to heavy
from functools import reduce

job = ['Sale', 'Dev', 'OPS', 'Sale', 'Presale', 'Sale', 'Dev', 'Test', 'OPS']
func = lambda x,y:x if y in x else x + [y]
jobs = reduce(func, [[], ] + job)

交叉编译详解概念篇

智慧运维 OS小编 发表了文章 0 个评论 91 次浏览 2020-11-01 01:53 来自相关话题

1、交叉编译简介1.1 什么是交叉编译对于没有做过嵌入式编程的人, 可能不太理解交叉编译的概念, 那么什么是交叉编译?它有什么作用? 在解释什么是交叉编译之前,先要明白什么是本地编译。 ...查看全部

1、交叉编译简介

1.1 什么是交叉编译

对于没有做过嵌入式编程的人, 可能不太理解交叉编译的概念, 那么什么是交叉编译?它有什么作用?


在解释什么是交叉编译之前,先要明白什么是本地编译。


本地编译:


本地编译可以理解为,在当前编译平台下,编译出来的程序只能放到当前平台(CPU和系统)下运行。平时我们常见的软件开发,都是属于本地编译:


比如,我们在 x86 平台上,编写程序并编译成可执行程序。这种方式下,我们使用 x86 平台上的工具,开发针对 x86 平台本身的可执行程序,这个编译过程称为本地编译。


交叉编译:


交叉编译可以理解为,在当前编译平台下,编译出来的程序能运行在体系结构不同的另一种目标平台上,但是编译平台本身却不能运行该程序:


比如,我们在 x86 平台上,编写程序并编译成能运行在 ARM 平台的程序,编译得到的程序在 x86 平台上是不能运行的,必须放到 ARM 平台上才能运行。


1.2 为什么会有交叉编译

之所以要有交叉编译,主要原因是:


  • Speed: 目标平台的运行速度往往比当前编译主机慢得多,许多专用的嵌入式硬件被设计为低成本和低功耗,没有太高的性能;
  • Capability: 整个编译过程是非常消耗资源的,嵌入式系统往往没有足够的内存或磁盘空间;
  • Availability: 即使目标平台资源很充足,可以本地编译,但是第一个在目标平台上运行的本地编译器总需要通过交叉编译获得;
  • Flexibility: 一个完整的Linux编译环境需要很多支持包,交叉编译使我们不需要花时间将各种支持包移植到目标机器上。

1.3 为什么交叉编译比较困难

交叉编译的困难点在于两个方面:


不同的体系架构拥有不同的机器特性


  • Word size: 是64位还是32位系统
  • Endianness: 是大端还是小端系统
  • Alignment: 是否必修按照4字节对齐方式进行访问
  • Default signedness: 默认数据类型是有符号还是无符号
  • NOMMU: 是否支持MMU

交叉编译时的主机环境与目标环境不同


  • Configuration issues:具有单独配置步骤(标准./configure make make install)的软件包通常会测试字节序或页面大小等内容,以便在本地编译时可移植。交叉编译时,这些值在主机系统和目标系统之间会有所不同,因此在主机系统上运行测试会给出错误的答案。当目标没有该程序包或版本不兼容时,配置还可以检测主机上是否存在该程序包并包括对该程序包的支持;
  • HOSTCC vs TARGETCC:许多构建过程需要编译内容才能在主机系统上运行,例如上述配置测试或生成代码的程序(例如创建.h文件的C程序,然后在主构建过程中#include )。仅用目标编译器替换主机编译器就会破坏需要构建在构建本身中运行的事物的软件包。这样的软件包需要访问主机和目标编译器,并且需要教它们何时使用它们;
  • Toolchain Leaks:配置不正确的交叉编译工具链可能会将主机系统的某些位泄漏到已编译的程序中,从而导致通常易于检测但难以诊断和纠正的故障。工具链可能#include错误的头文件,或在链接时搜索错误的库路径。共享库通常依赖于其他共享库,这些共享库也可能潜入对主机系统的意外链接时引用;
  • Libraries:动态链接的程序必须在编译时访问适当的共享库。需要将与目标系统共享的库添加到交叉编译工具链中,以便程序可以针对它们进行链接;
  • Testing:在本机版本上,开发系统提供了便利的测试环境。交叉编译时,确认”hello world”构建成功可能需要配置(至少)引导加载程序,内核,根文件系统和共享库。

更详细的对比可以参看这篇文章,已经写的很详细了,在这就不细说了:Introduction to cross-compiling for Linux


2、交叉编译链

2.1 什么是交叉编译链

明白了什么是交叉编译,那我们来看看什么是交叉编译链。


首先编译过程是按照不同的子功能,依照先后顺序组成的一个复杂的流程,如下图:

那么编译过程包括了预处理、编译、汇编、链接等功能。既然有不同的子功能,那每个子功能都是一个单独的工具来实现,它们合在一起形成了一个完整的工具集。


同时编译过程又是一个有先后顺序的流程,它必然牵涉到工具的使用顺序,每个工具按照先后关系串联在一起,这就形成了一个链式结构。


因此,交叉编译链就是为了编译跨平台体系结构的程序代码而形成的由多个子工具构成的一套完整的工具集。同时,它隐藏了预处理、编译、汇编、链接等细节,当我们指定了源文件(.c)时,它会自动按照编译流程调用不同的子工具,自动生成最终的二进制程序映像(.bin)。



注意: 严格意义上来说,交叉编译器,只是指交叉编译的gcc,但是实际上为了方便,我们常说的交叉编译器就是交叉工具链。本文对这两个概念不加以区分,都是指编译链。



2.2 交叉编译链的命名规则

我们使用交叉编译链时,常常会看到这样的名字:


arm-none-linux-gnueabi-gcc
arm-cortex_a8-linux-gnueabi-gcc
mips-malta-linux-gnu-gcc

其中,对应的前缀为:


arm-none-linux-gnueabi-
arm-cortex_a8-linux-gnueabi-
mips-malta-linux-gnu-

这些交叉编译链的命名规则似乎是通用的,有一定的规则:


arch-core-kernel-system
  • arch: 用于哪个目标平台;
  • core: 使用的是哪个CPU Core,如Cortex A8,但是这一组命名好像比较灵活,在其它厂家提供的交叉编译链中,有以厂家名称命名的,也有以开发板命名的,或者直接是none或cross的;
  • kernel: 所运行的OS,见过的有Linux,uclinux,bare(无OS);
  • system: 交叉编译链所选择的库函数和目标映像的规范,如gnu,gnueabi等。其中gnu等价于glibc+oabi、gnueabi等价于glibc+eabi。

注意: 这个规则是一个猜测,并没有在哪份官方资料上看到过。而且有些编译链的命名确实没有按照这个规则,也不清楚这是不是历史原因造成的。如果有谁在资料上见到过此规则的详细描述,欢迎指出错误。



3、包含的工具

Binutils是GNU工具之一,它包括链接器、汇编器和其他用于目标文件和档案的工具,它是二进制代码的处理维护工具。


Binutils工具包含的子程序如下:


  • ld - GNU链接器;
  • as - GNU汇编器;
  • gold - 一个新的,更快的ELF链接器;
  • addr2line - 把地址转换成文件名和所在的行数;
  • ar - 用于创建,修改和提取档案的实用程序;
  • c ++ filt-过滤以解编码编码的C ++符号;
  • dlltool-创建用于构建和使用DLL的文件;
  • elfedit-允许更改ELF格式文件;
  • gprof-显示分析信息;
  • nlmconv-将目标代码转换为NLM;
  • nm-列出目标文件中的符号;
  • objcopy-复制并转换目标文件;
  • objdump-显示目标文件中的信息;
  • ranlib-生成指向档案内容的索引;
  • readelf-显示来自任何ELF格式对象文件的信息;
  • size -列出的对象或归档文件的部分的尺寸;
  • strings -列出文件中的可打印字符串;
  • strip - 丢弃的符号;
  • windmc -Windows兼容的消息编译器。
  • windres -Windows资源文件的编译器。

binutils介绍 binutils详解 详细页面。


3.2 GCC

GNU编译器套件,支持C, C++, Java, Ada, Fortran, Objective-C等众多语言。


3.3 Glibc

Linux上通常使用的C函数库为glibc。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装linux操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。


glibc 各个库作用介绍


因为嵌入式环境的资源及其紧张,所以现在除了glibc外,还有uClibc和eglibc可以选择,三者的关系可以参见这两篇文章:


uclibc eglibc glibc之间的区别和联系


Glibc vs uClibc Differences


3.4 GDB

GDB用于调试程序


4、如何得到交叉编译链

既然明白了交叉编译链的功能,那么在针对嵌入式系统开发时,我们需要的交叉编译链从哪儿得到?


主要有三个方式可以获取


4.1 下载已经做好的交叉编译链

使用其他人针对某些CPU平台已经编译好的交叉编译链。我们只需要找到合适的,下载下来使用即可。


常见的交叉编译链下载地址:


http://ftp.arm.linux.org.uk/pub/armlinux/toolchain/ 下载已经编译好的交叉编译链
http://www.denx.de/en/Software/WebHome 下载已经编译好的交叉编译链
https://launchpad.net/gcc-arm-embedded下载已经编译好的交叉编译链
一些制作交叉编译链的工具中,包含了已经制作好的交叉编译链,可以直接拿来使用。如crosstool-NG
如果购买了某个芯片或开发板,一般厂商会提供对应的整套开发软件,其中就包含了交叉编译链。
厂家提供的工具一般是经过了严格的测试,并打入了一些必要的补丁,所以这种方式往往是最可靠的工具来源。

4.2 使用工具定制交叉编译链

使用现存的制作工具,以简化制作交叉编译链这个事情的复杂度。我们只需要了解有哪些工具可以实现,并选个合适的工具,搞懂它的操作步骤即可。


  1. crosstool-NG
  2. Buildroot
  3. Embedded Linux Development Kit (ELDK)

工具还有很多,各有各的优势和劣势,大家可以慢慢研究,在这就不细说了。


4.3 从零开始构建交叉编译链

这个是最困难也最耗时间的,毕竟制作交叉编译链这样的事情,需要对嵌入式的编译原理了解的比较透彻,至少要知道出了问题要往哪个方面去翻阅资料。而且,也是最考耐心和细心的地方,配错一个选项或是一个步骤,都可能出现以前从来没见过的问题,而且这些问题往往还无法和这个选项或步骤直接联系起来。


当然如果搭建出来,肯定也是收获最大的,至少对于编译的流程和依赖都比较清楚了,细节上的东西可能还需要去翻看相应的协议或标准,但至少骨架会比较清楚。


详细的搭建过程可以参看后续的文章,这里面有详细的参数和步骤:
交叉编译详解 二 从零制作交叉编译链


为了方便大家搭建交叉编译链,我写了一个一键生成的脚本(包括源码下载和自动编译)。如果大家自己一直搭建不成功,不妨试试这个脚本,然后对比下自己的流程是否一致,参数是否有差异,也许能帮大家迈过这个障碍:
交叉编译详解 三 使用脚本自动生成交叉编译链


4.4 对比三种构建方式




























项目 使用已有交叉编译链 自己制作交叉编译链
安装 一般提供压缩包 需要自己打包
源码版本 一般使用较老的稳定版本,对于一些新的GCC特性不支持 可以使用自己需要的GCC特性的版本
补丁 一般都会打上修复补丁 普通开发者很难辨别需要打上哪些补丁,资深开发者可以针对自己的需求合入补丁
源码溯源 可能不清楚源码版本和补丁情况 一切都可以定制
升级 一般不会升级 可以随时升级
优化 一般已经针对特定CPU特性和性能进行优化 一般无法做到比厂家优化的更好,除非自己设计的CPU
技术支持 可以通过FAE进行支持,可能需要收费 只能通过社区支持,免费
可靠性验证 已经通过了完善的验证 自己验证,肯定没有专业人士验证的齐全

参考资料

1、Introduction to cross-compiling for Linux


2、binutils介绍


3、 glibc 各个库作用介绍


4、 uclibc eglibc glibc之间的区别和联系


5、 Glibc vs uClibc Differences


6、交叉编译链下载地址


分享原文: http://m6z.cn/6tdD7y

国产化龙芯mips下编译安装ClickHouse

数据库 OS小编 发表了文章 0 个评论 68 次浏览 2020-10-31 23:39 来自相关话题

基础环境Linux ningmei-PC ...查看全部

基础环境

Linux ningmei-PC 4.19.0-loongson-3-desktop #1143 SMP PREEMPT Thu Mar 5 21:00:31 CST 2020 mips64 GNU/Linux
系统:USO 20
默认支持:gcc-8
Clickhouse 版本:ClickHouse 20.1.6.30

环境准备

sudo apt-get install git cmake python ninja-build
sudo apt-get install gcc-8 g++-8

// clone Clickhouse 代码
git clone --recursive -b v20.1.6.30-stable
tar -zcvf clickhouse-src-v20.1.6.30-stable.tar.gz ClickHouse

源码修改

// dbms/src/Compression/LZ4_decompress_faster.cpp
// 参考
// copyOverlap8Shuffle 函数添加 mips 支持, 209 行左右
#ifdef __mips__

inline void copyOverlap8Shuffle(UInt8 * op, const UInt8 *& match, const size_t offset)
{
copyOverlap8(op, match, offset);
}

#endif


// copyOverlap16Shuffle 函数添加 mips 支持, 350 行左右
#ifdef __mips__

inline void copyOverlap16Shuffle(UInt8 * op, const UInt8 *& match, const size_t offset)
{
copyOverlap16(op, match, offset);
}

#endif
// dbms/src/Core/Defines.h 假装支持
#if !defined(__x86_64__) && !defined(__aarch64__) && !defined(__PPC__)
修改为:
#if !defined(__x86_64__) && !defined(__aarch64__) && !defined(__PPC__) && !defined(__mips__)
// contrib/poco/Foundation/src/SHA3Engine.cpp 210 行添加
// 参考

#define nrLanes 25

static void fromBytesToWords(UInt64 *stateAsWords,
const unsigned char *state) {
unsigned int i, j;

for (i = 0; i < nrLanes; i++) {
stateAsWords[i] = 0;
for (j = 0; j < (64 / 8); j++)
stateAsWords[i] |= (UInt64)(state[i * (64 / 8) + j]) << (8 * j);
}
}

static void fromWordsToBytes(unsigned char *state,
const UInt64 *stateAsWords) {
unsigned int i, j;

for (i = 0; i < nrLanes; i++)
for (j = 0; j < (64 / 8); j++)
state[i * (64 / 8) + j] =
(unsigned char)((stateAsWords[i] >> (8 * j)) & 0xFF);
// ucontext 支持 mips
// 参考

#if defined(__x86_64__) && !defined(__FreeBSD__) && !defined(__APPLE__) && !defined(__arm__)
改为
#if defined(__x86_64__) && !defined(__FreeBSD__) && !defined(__APPLE__) && !defined(__arm__) && !defined(__mips__)


// getCallerAddress 函数里面追加

#elif defined(__mips__)
return reinterpret_cast(context.uc_mcontext.pc);

编译安装

mkdir build && cd build
CC=clang-8 CXX=clang++-8

// 执行 cmake
cmake .. \
-DGLIBC_COMPATIBILITY=NO \
-DUSE_CPUID=0 \
-DUSE_CPUINFO=0 \
-DBUILD_TESTING=NO \
-DENABLE_TESTS=NO \
-DENABLE_SSL=NO \
-DENABLE_NETSSL=NO \
-DENABLE_S3=NO \
-DENABLE_HDFS=NO \
-DENABLE_REDIS=YES \
-DENABLE_MYSQL=NO \
-DENABLE_MONGODB=NO \
-DENABLE_RDKAFKA=NO \
-DENABLE_ORC=NO \
-DENABLE_PARQUET=NO \
-DENABLE_PROTOBUF=NO \
-DENABLE_JEMALLOC=NO \
-DENABLE_READLINE=NO \
-DENABLE_FASTOPS=NO \
-DENABLE_POCO_MONGODB=NO \
-DENABLE_CLICKHOUSE_PERFORMANCE_TEST=NO \
-DUSE_UNWIND=NO \
-DNO_WERROR=1


// 编译
ninja

// 打包
cpack --config CPackConfig.cmake

编译选项说明

GLIBC_COMPATIBILITY
依赖高版本 glibc 的程序能在低版本 glibc 运行,目前不支持 mips
影响范围:兼容性,比如 CentOS7 上编译的ck不能在 CentOS6 上运行

USE_CPUID
获取 CPU 相关信息,ck 中使用它获取 cpu 的物理核数
影响范围:目前是在编译阶段获取到核数,兼容性,4 核设备编译出来的在8核上不能高效使用8核

BUILD_TESTING:
影响范围:不编译 CTest,不影响功能

ENABLE_TESTS:
不开启测试
影响范围:不启用 ck 的单元测试

ENABLE_SSL:
安全连接,目前不支持 mips
影响范围:不能启用 https 及 tcp 安全连接

S3、MYSQL、MONGODB、RDKAFKA、ORC、PARQUET
影响范围:不支持以上数据源的直接对接

USE_UNWIND:
异常时的堆栈优化展示
影响范围:抛出异常时堆栈不够人性化

性能上龙芯暂时没有 SIMD 相关指令,不能实现向量优化

更多话题 >>

热门话题

网络安全

5 个问题, 2 人关注

Go进阶笔记

2 个问题, 1 人关注

更多用户 >>

热门用户

peanut

6 个问题, 3 次赞同

空心菜

148 个问题, 106 次赞同