纳秒时代

article/2025/9/20 23:45:33

    

    1978年在英特尔公司的历史中是很不平凡的一年。这一年它满10岁了,员工数首次超过1万人。这一年,它卖掉了竞争激烈的电子表(digital watch)业务。最重要的是,在这一年6月,它推出了具有跨时代意义的8086芯片。

640?wx_fmt=jpeg

    在8086的宣传彩页里,第一页画着一轮初升的太阳。标题写着“8086的时代已经来了。”

640?wx_fmt=jpeg

    太多人喜欢8086了,据说它的生产一直持续到90年代。它如此完美,让很多同行都想模仿。它的后代很多,形成一个庞大的x86谱系。

    8086的工作频率有5M、8M、10M和4M等多种,最初版本是5MHz。这意味着,每个时钟周期的时间是:

    1/(5*10^6) 秒= 0.2 * 10^-6秒 = 0.2微妙

    在从1978年开始的20多年中,8086及其后代风行天下。工作频率不断提升,1994年的改进版本奔腾处理器首次达到100MHz。

Intel® Pentium® Processor100 MHz
90 MHz
Mar. 7, 19940.6-micron3.3 million


Desktops

    2000年5月,改进版本的奔腾III处理器发布,首次达到1GHz主频。在22年时间里,8086的工作频率从5MHz发展到1GHz,刚好200倍。

Intel®
Pentium® III
Processor
1 GHz
933 MHz
866 MHz
850 MHz
May-000.18-micron28 million256 KB
Advanced
Transfer
Cache


    同年11月,包含众多新设计的奔腾4处理器首次发布,把最高工作频率的纪录刷新为2GHz。

    在接下来的几年中,英特尔的奔腾4团队持续努力,向4GHz主频冲刺。所做的努力是多方面的。一方面是改进生产工艺,把晶体管做小。2004年初,英特尔发布90nm工艺的奔腾4。这标志着芯片生产工艺从微米计量进入到纳米。另一方面是增大风扇,提高散热能力。奔腾4的微架构名叫NetBurst,别名火球。内部运算单元的流水线特别长。这样的流水线在高频率下工作时会产生大量的热量。2003年,我加入英特尔。最初的一些项目都是基于奔腾4的,至今还记得当年那些个头很大的风扇,转速很大,声音很响。

    无论如何,奔腾4向4G主频冲刺的目标没能实现。据说,当时的CEO,Craig Barrett曾经向合作伙伴诚恳道歉,因为没有实现承诺。

    或许是上帝已经安排了,或许任何事物的发展都应该有个极限,或许就该在这里多停留一些时间。

    2006年1月,英特尔发布最后一款奔腾4,这不仅意味着一个微架构的结束,也意味着依靠提高频率来不断提升性能的时代结束了。从此,整个产业开始向多核方向发展。一个时代结束了,多核时代开始了。

640?wx_fmt=gif

    从上面这幅来自Tom's Hardware的频率走势图来看,2004年左右,频率达到3.8GHz的高峰,而后出现回调。

   2018年7月,英特尔为了纪念8086发布40年,也是为了纪念整个公司成立50年,特别发布了一个特殊版本酷睿i7处理器,取名为8086K。    640?wx_fmt=png

    8086K的标称频率为4GHz,最高工作频率为5GHz,刚好是40年前的8086始祖的1000倍。40年时间,从5MHz发展到5GHz。

    # of Cores 6

    # of Threads 12

    Processor Base Frequency 4.00 GHz

    Max Turbo Frequency 5.00 GHz

    Cache 12 MB SmartCache

    Bus Speed 8 GT/s DMI3

    TDP 95 W


    今天,大多数处理器的频率都是1~5GHz,从低端的ARM芯片,到高端的i7、i9以及至强(Xeon)。

    对于1~5GHz的处理器,每个时钟周期的时间是多久呢?

    1/((1~5)*10^9)=1~0.2*10^-9秒 = 1~0.2纳秒

    对于跳频工作在5GHz的8086K来说,每个时钟周期的长度是0.2纳秒,刚好是始祖8086的千分之一。40年时间,每个时钟周期,从0.2微妙加快到0.2纳秒(ns)。换言之,在1纳秒时间里,8086K最多可以跑5个时钟。

    1纳秒是多长时间呢?以光来衡量的话,1纳秒时间里,光可以在真空中行进大约30厘米。

    光速大约30万公里每秒 3*10 * 10^4 * 10^3m/s

    1 ns = 10^ -9 s

    d = 3*10^8*10^-9 =3*10^-1 m = 0.3m

    为了更简略地描述这个距离,科学家们创造了一个专门的单位,叫光尺(light-foot)。简单说,“光的速度是每纳秒一英尺”("The speed of light is one foot per nanosecond.“),其精确长度是29.9792458 cm

,与普通的1英尺(30.48厘米)略有差别。

    现代计算机的一位伟大拓荒者,编译器的发明人,Grace Hopper曾经努力推动光尺这个计量单位,鼓励大家使用这个单位来更精确地计量、思考和交流。

640?wx_fmt=jpeg

    顺便说一下,美国海军的著名导弹驱逐舰(Missile Destroyer) USS Hopper(DGG 70)就是为纪念Grace Hopper而命名的。在这个军事站点有很详细的介绍,https://www.navysite.de/dd/ddg70.htm。

640?wx_fmt=jpeg

    

      下面这张表格归纳了计算机世界里常见操作所需的时间。

640?wx_fmt=jpeg

    从这张表里,可以看出,CPU是在纳秒级别工作的。对于内部有多条流水线的x86处理器来说,每纳秒可以跑几条,甚至十几条指令(与指令类型和CPI有关)。

    

    那么在今天,优化软件时应该如何计量时间呢?首先值得说明的是,一些老的取时间的方法已经跟不上时代了。比如,POSIX标准中的clock()函数的时间精度只有10ms。

    很多程序中使用gettimeofday()来取时间,它的精度如何呢?其实也只能达到微秒级别(下文会通过试验来测试)。

    对于需要深度优化的场景,今天最好的取时间方法是使用CPU的专有机制来读取CPU的时间戳计数器,比如x86的rdtsc指令。

640?wx_fmt=jpeg

    关于rdtsc指令,很多同行有个困惑。既然今天的CPU常常会自动调频工作,那么rdtsc读到的时钟数会不会快慢不均呢?

    其实这个顾虑是不必要的。虽然英特尔的手册里没有明确说明这个问题,但其实rdtsc返回的时钟数总是已经按CPU的标定频率做过规范化的。

    比如,在笔者的E580 Thinkpad上,CPU的标称频率是1.8GHz。在Linux系统中,执行lscpu命令,在Model name中包含着标称频率。    

Architecture:        x86_64

CPU op-mode(s):      32-bit, 64-bit

Byte Order:          Little Endian

CPU(s):              8

On-line CPU(s) list: 0-7

Thread(s) per core:  2

Core(s) per socket:  4

Socket(s):           1

NUMA node(s):        1

Vendor ID:           GenuineIntel

CPU family:          6

Model:               142

Model name:          Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz

Stepping:            10

CPU MHz:             800.036

CPU max MHz:         4000,0000

CPU min MHz:         400,0000

BogoMIPS:            3984.00

Virtualization:      VT-x

L1d cache:           32K

L1i cache:           32K

L2 cache:            256K

L3 cache:            8192K

NUMA node0 CPU(s):   0-7

Flags:               fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp flush_l1d

    其中的CPU MHz是实际工作频率,多次执行lscpu,可以看到这个值是经常变化的。

    通过一小段代码就可以感受到tdtsc返回的时钟数是稳定的,不会受频率跳动的影响。

int measure_sleep(int us)

{

    long begin, end,delta;

    int i=0;

    for(int i=0;i<10;i++)

    {

        begin = __builtin_ia32_rdtsc();

        usleep(us);

        end = __builtin_ia32_rdtsc();

        delta += end - begin;

    }

    printf("usleep(%ld) 10 times took %ld ticks. %ld ticks in average.\n",

         us, delta, delta/10);        

}

    编译执行这段代码,然后绑定7号CPU执行:

    taskset 80 ./nano s 1000000

    故意sleep 1s时间,其结果为:   

Nano utility by Raymond rev0.1 2018/12/30

usleep(1000000) 10 times took 19927224841 ticks. 1992722484 ticks in average.

    重复执行多次,可以看到只有后面的四位略有波动。其结果约为1.99G,理论上,1秒钟的标称时钟数应该为1.8G,但因为实际执行时,ussleep内包含系统调用,还有线程挂起和唤醒的时间,所以数值超过了1.8G。

    使用下面的函数,可以策略测量gettimeofday的精度。

int gtd_resolution(long loops)

{

    struct timeval t1,t2;

    long begin, end;

    long i = loops;


    begin = __builtin_ia32_rdtsc();


    while(i--)

    {

        gettimeofday(&t1);

        do {

            gettimeofday(&t2);        

        }while(t2.tv_usec==t1.tv_usec);

    };

    end = __builtin_ia32_rdtsc();


    printf("Resolution of gettimeofday is %f ticks.\n", (end-begin)*1.0/loops);

    return 0;

}

    上面代码反复调用gettimeofday函数,记录所取到微秒数变化时的时钟间隔数。在E580上测试到的结果为大约1微妙。    

gedu@ThinkE580:~/labs/nano$ ./nano r

Nano utility by Raymond rev0.1 2018/12/30

Resolution of gettimeofday is 1997.566240 ticks.

    

    伟大的Grace Hopper很早预见到了纳秒计量的意义。可惜,她没能看到每纳秒跳动几个时钟的计算机。

    无比幸运,我们今天正在经历着计算机的纳秒时代。在纳秒级别对软件做优化是很有挑战也非常有趣的一个领域。

    在2018年即将结束之际,特别写作这样一篇短文,纪念这个具有独特意义的年份,也作为格蠹科技公众号的开篇之作。各位朋友,新年快乐!


*****************************

格蠹科技(XEDGE.AI)致力于纳秒级软件优化,发挥芯片每个时钟的效能,提供快速高可用的软件栈

欢迎关注格蠹科技官方公众号

    

640?wx_fmt=jpeg



http://chatgpt.dhexx.cn/article/oli3Njya.shtml

相关文章

linux内核纳秒精度时间,Linux时钟精度:毫秒?微妙?纳秒?

最近被内核时钟精度弄的很是郁闷。具体情况如下&#xff1a; 扫盲&#xff1a;1秒1000毫秒1000000微妙1000000000纳秒 首先&#xff1a;linux有一个很重要的概念——节拍&#xff0c;它的单位是(次/秒)。2.6内核这个值是1000&#xff0c;系统中用一个HZ的宏表征这个值。同时有全…

java 日期 纳秒_java8 ZonedDateTime 日期精度到纳秒

1秒 10E3毫秒 10E6 微妙 10E9 纳秒 使用java8 Instant 内部实际System.currentTimeMillis() 在模型上 可输出纳秒数据 重点是模型 时间戳转日期 public static ZonedDateTime ofInstant(Instant instant, ZoneId zone) { Objects.requireNonNull(instant, "instant&qu…

第九章:NAT(网络地址转换协议)

文章目录 一、NAT1、NAT介绍①公有网络地址②私有网络地址 2、NAT工作原理3、NAT功能 二、NAT的实现方式1、静态转换&#xff08;static Translation&#xff09;实验对比 2、动态转换2.1 ACL&#xff08;访问控制列表&#xff09;2.2 配置动态NAT实验效果 3、端口多路复用3.1 …

【NAT网络地址转换(私网公网地址、静态NAT、动态NAT、NAPT、Easy IP、NAT Server)】-20211215、20211216

目录 一、NAT产生背景 1.产生背景 2.私网地址、公网地址​ 私网IP地址&#xff0c;既可以一定上缓解ip的不足&#xff0c;在私网里&#xff0c;ip地址可以随意使用。 公网地址&#xff0c;在需要访问公网时&#xff0c;运用网络地址转换NAT技术&#xff0c;可以实现。 二…

什么是私网,公网?

我们常说的内网和外网&#xff0c;通常是相对于防火墙而言的&#xff0c;在防火墙内部叫做内网&#xff0c;反之就是外网。 在一定程度上外网等同于公网&#xff0c;内网等同于私网。公网地址 公网地址是指在因特网上直接可达的地址&#xff0c;如果你有一个公网地址&#xff0…

NAT——公私网地址转换

NAT—网络地址转换 NAT NAT又称为网络地址转换&#xff0c;用于实现私有网络和公有网络之间的转换 私有和公有网络地址 公有网络地址是指互联网上全球唯一的IP地址 私有网络地址是指内部网络或者主机的IP地址 IANA&#xff08;互联网数字分配机制&#xff09;规定将下列的IP地…

公网地址和私网地址问题

服务器映射用于将内网服务器的私网地址映射为公网地址&#xff0c;供Internet用户访问。选择“静态映射”类型可以将每一台服务器映射成一个独立的公网IP地址。“服务器负载均衡”类型可以将多台服务器映射成同一个公网地址&#xff0c;Internet用户在访问这个公网地址时&#…

私网地址与Internet地址

一、A、B、C三类地址 可用地址范围备注A类1.0.0.1-126.255.255.254B类128.1.0.1-191.255.255.254C类192.0.1.1-223.255.255.254D类224.0.0.1-239.255.255.254D类为多播地址 说明&#xff1a; 1. 每一个地址都是用网络位主机位组成的。 2. 全0的和全1的网络位和主机位都要去掉…

计算机网络 网络层 私网地址和公网地址及子网划分

公网地址 公有地址分配和管理由Inter NIC&#xff08;Internet Network Information Center 因特网信息中心&#xff09;负责。各级ISP使用的公网地址都需要向Inter NIC提出申请&#xff0c;有Inter NIC统一发放&#xff0c;这样就能确保地址块不冲突。 私网地址&#xff08;不…

为什么百度查到的ip和ipconfig查到的不一样;详解公网Ip和私网ip;详解网络分类ABC;

IP可以分为Public IP 和 Private IP,出现这种规划的原因在于IPv4所能表示的IP太少而电脑太多以至于不够用&#xff0c;然而只有Public IP才能直接连接上网络&#xff0c;所以对于那些公司&#xff0c;学校&#xff0c;政府机构等场所&#xff0c;就可以集中使用私有的IP进行管理…

挑战华为社招:掌握数据库其实很容易

前言 我的一个朋友,开发四年了,没跳过槽,四年时间也不过是从最开始的10K涨到了15K,经常和我吐槽工资低。去年8月份左右开始了他“骑驴找马”的行动,从各种地方找学习资料、刷面试题。值得庆幸的是,他出去找工作时疫情还不严重,异常顺利的面进了蚂蚁,薪资更是翻了几倍。…

javaspringboot面试,挑战华为社招

前言 redis简单来说 就是一个数据库&#xff0c;不过与传统数据库不同的是 redis 的数据是存在内存中的&#xff0c;所以存写速度非常快&#xff0c;因此 redis 被广泛应用于缓存方向。另外&#xff0c;redis 也经常用来做分布式锁。redis 提供了多种数据类型来支持不同的业务…

挑战华为社招:不止面试题,笔记源码统统都有,最强技术实现

前言 说起来开始进行面试是11月倒数第二周&#xff0c;上午9点&#xff0c;我还在去公司的公交上&#xff0c;突然收到蚂蚁的面试电话&#xff0c;其实算不上真正的面试。面试官只是和我聊了下他们在做的事情&#xff08;主要是做双十一这里大促的稳定性保障&#xff0c;偏中间…

挑战华为社招:字节跳动上千道精选面试题还不刷起来

前言 成为优秀的架构师是大部分初中级工程师的阶段性目标。优秀的架构师往往具备七种核心能力&#xff1a;编程能力、调试能力、编译部署能力、性能优化能力、业务架构能力、在线运维能力、项目管理能力和规划能力。 这几种能力之间的关系大概如下图。编程能力、调试能力和编…

华为社招面试

工作第三年&#xff0c;在某招聘软件上填写简历后接到华为HR面试邀请&#xff0c;面试部门为运营商路由器&#xff0c;网上查看岗位相关要求之后发现与自己十分不匹配&#xff0c;不过机会难得&#xff0c;所以决定抱着学习的态度去参加面试。 2018年3月3号周六前往华为北研所Q…

华为社招技术二面,总结复盘

点击上方“Java基基”&#xff0c;选择“设为星标” 做积极的人&#xff0c;而不是积极废人&#xff01; 源码精品专栏 原创 | Java 2020 超神之路&#xff0c;很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数…

华为社招三面面经分享,现已拿到offer,定级D4对标17级

一面&#xff1a;&#xff08;面试均是华为的开发&#xff0c;每轮面试完都有反问你想了解的&#xff09; 修饰符和可见性抽象类抽象方法synchronized&#xff0c;volatile一些java类型相关的基础知识&#xff0c;比如springbuilder和springbuffer哪个线程安全为什么要使用spr…

华为社招面试(拿到offer)

前段时间华为主动联系我要不要面试&#xff0c;抱着试一下的心态接受了面试邀请&#xff0c;最后顺利拿到了offer&#xff0c;不过最终由于方方面面的原因还是没有去。 本文主要分享下&#xff0c;面试的大致过程。 1. 初步电话技术面试 主要问了下&#xff0c;项目C的后台开…

5年测试经验华为社招:半月3次面试,成功拿到Offer

背景经历 当时我工作近5年&#xff0c;明显感觉到了瓶颈期。具体来说&#xff0c;感觉自己用过很多测试框架和测试工具、做过一些测试开发、也有过高并发的性能测试&#xff0c;但是从技术深度上感觉不足&#xff0c;到后期时做事也没有明显挑战&#xff0c;完全适应了公司节奏…