从计算机体系结构到高性能编程实践(一)

上来先推荐一本书,《计算机体系结构:量化研究方法(第五版)》,英文能力比较好的建议阅读原版。

大部分情况写程序是不需要考虑体系结构的影响的,尤其是对于解释型语言(比如Python)和在虚拟机上运行的语言(比如Java)考虑体系结构没有什么意思,因为最终生成的机器指令并不是自己的应用程序可以控制的。

目前只有C语言相关的多核高性能编程经验,所以这里只说C语言。对于C语言程序来说,如果出现了性能瓶颈,我在优化时一般会从下面几个点入手:

  • 算法
  • 编译器
  • 操作系统
  • 体系结构

一个系统说白了就是三点组成的,输入,处理,输出。

当出现性能瓶颈时算法层面是应该最先考虑的,比如对数据排序选择哪一种排序算法,对数据查找时如果内存足够大是否可以空间换时间,查表法,状态机等等,具体算法的选择一般要根据实际的数据进行测试之后再做决定。

当算法的优化已经达到自己能力极限的时候,下一步会考虑编译器的优化,主要是通过明确指定编译器提供的一些高级编译选项或者扩展函数来让gcc生成更加高效的CPU指令,比如编译时指定O3选项,likely和unlikely相关的分支预测,for循环中的公共子表达式提取,对某些小短函数加上inline等等。

编译器优化选项榨干之后会从操作系统层面继续进行优化。平时写的服务端程序都是跑在linux上,linux内核其实内部有很多高级的特性,但是linux发布版本本身要考虑通用性,所以很多的参数特性默认是关闭的。可以根据自己的机器配置打开一些特有的对性能有提高的参数,比如网络协议栈的一些参数,文件系统IO的一些参数,对于CPU高级特性支持的一些参数等。

终于到了体系结构层面了,如果程序需要在体系结构层面进行优化,一般来说就是控制每一条指令的执行时间了,要把对数据的处理细化到cycle级别。这个里面最好的一个计算模型就是网络数据包的处理了,我之前的高性能计算经验也是在开发网络数据包处理系统上获得的,那个时候DPDK还没有开源。

先简单计算一下,网络上传输的最小的Ethernet包是64字节,再加上物理层需要的8Bytes的前导码以及每两个包之间12Bytes的Gap,对于一个10Gbps的网络来说,如果处理性能要达到线速,那么每秒钟处理的数据包的个数可以通过下面的公式计算出来:

(10000000000 / 8) / (64+20) = 14880952 packets/s

也就是说每个数据包必须在67ns内处理完,否则就会丢包(不考虑网卡DMA小缓存的情况)。 67ns是什么概念呢,可能很多同学不知道,但是我们对比一下就能看出这个时间有多么的短暂。一个Mutex lock的时间就是25ns,一次主存的访问时间就是100ns。

从上面量化的数据来讲,一旦有一个数据包在处理过程中产生的cache miss,那么这个数据包相关的信息就要去Memory中取,然后时间就超了67ns了,然后就会发现网卡丢包了。就是这么残酷。

啰里八嗦说了好多前言的东西,感觉还没开始说重点。这个是一系列的文章,会写一个简单的L2-L7层TCP数据包处理小系统,从代码层面把自己掌握的各种性能优化技巧分享一遍,初步估计在30篇文章。目前想到的大致的主题如下:

  • 数据结构定义,struct中的field顺序以及大小都是有讲究的
  • NUMA结构下的内存分配,避免性能忽高忽低
  • NUIOA结构下如何设置CPU亲和性,性能可能差10倍
  • 高性能无锁队列的设计,多核之间如何通信
  • 如何对整个数据包的流水线处理进行设计,多核map reduce
  • GCC编译选项优化
  • 基于Malloc实现自己的高效内存管理
  • 设计高性能的hash算法加速tcp会话流查找
  • 引入向量指令加速字符串处理
  • 利用CPU硬件的某些特性加速,数据预取,指令预取,分支预测等
  • 使用Perf tool对性能进行测试以及查找性能瓶颈

希望写的文章能够让每个人得到每个人想要的。

陈阿福说

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏韩伟的专栏

腾讯的热更新方案开源了

xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,凭借其出色的性能,易用性,扩展性而广受好评。现在xLua开源...

7533
来自专栏数据小魔方

扒一扒rvest的前世今生!

rvest包可能是R语言中数据抓取使用频率最高的包了,它的知名度和曝光度在知乎的数据分析相关帖子和回答中都很高。 甚至很多爬虫教程和数据分析课程在讲解R语言网络...

3857
来自专栏炉边夜话

免费的午餐已经结束,你准备好了吗?

2005年3月,C++大师Herb Sutter在Dr.Dobb’s Journal上发表了一篇名为《免费的午餐已经结束》的文章,一石激起千层浪,该文引起了社区...

942
来自专栏Vamei实验室

Linux文本流

我之前已经用文本编辑器修改过文本。现在,我们要深入理解所谓的“文本”。 文本流 在计算机中,所谓的数据就是0或1的二进制序列,但严格来说,Unix以字节(byt...

2599
来自专栏王清培的专栏

数据分表小结

本次拆分主要包括订单和优惠券两大块,这两块都是覆盖全集团所有分子公司所有业务线。随着公司的业务飞速发展,不管是存储的要求,还是写入、读取的性都基本上到了警戒水位...

1070
来自专栏双十二技术哥

组件化实践详解(一)

具体实施一项技术项目之前我们会首先确定对应的目标,之后的行动计划都会朝着目标一步步靠拢。

732
来自专栏卡少编程之旅

REACT框架学习心得

3537
来自专栏linux驱动个人学习

SPI通讯协议

一、SPI概述 SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口。SPI,是一种高速的,全双工,同步的通...

4347
来自专栏狮乐园

从ng1看ng2 关于NgModule的简易归纳

最近开始折腾ng2,其实说是ng2,到目前为止,它已经发布了4.3版,就是这么的高产,高产似*,我连2都还木有完整的看完它竟然发布了4.的版本(鄙视脸)。

1372
来自专栏LET

CPU Cache简介

真空中光速为299,792,458米/秒,目前,Intel的i7频率可以达到4GHz,简单换算一下,可以得出结论:光(电流)在一个Cycle内移动的距离约为0....

1982

扫码关注云+社区

领取腾讯云代金券