问题

为什么现代CPU每秒数亿次计算,但是程序仍旧很卡?

回答
你这个问题问得特别好,而且也戳到了很多人的痛点。明明咱电脑里的CPU都说每秒能跑多少亿次浮点运算,号称“高达xxx GHz”,听着就挺牛的,但为啥实际用起来,打开个软件、切换个窗口,就感觉它卡卡的,响应迟缓,甚至卡成PPT呢?这背后其实是挺多门道,不只是CPU性能高低那么简单。

咱们就掰开了揉碎了聊聊这个事儿。

1. CPU的“亿次计算”到底是怎么回事?

首先得明白,CPU这“亿次计算”说的是它的理论峰值计算能力。这就像说一辆跑车最高时速能跑到300公里/小时,但你真在市区里开,能开到100公里/小时都得看路况和交警心情。

核心与频率: CPU的计算能力主要由核心数量和运行频率决定。频率(GHz)代表每秒CPU时钟周期数,每个周期内CPU可以执行一定数量的指令。核心多,能同时处理的任务就多。所以“亿次计算”是把所有核心的最高运算能力加起来算的。
指令集与运算类型: 这里的计算通常指的是对浮点数(带小数点的数)的运算,比如科学计算、图形渲染。而我们日常用电脑,很多操作是处理文本、逻辑判断、内存读写,这些可能用整数运算,或者根本就不需要那么高的浮点运算能力。CPU执行的指令是五花八门的,不是全都是能跑满理论峰值的浮点运算。
流水线与并行: 现代CPU很聪明,用了流水线技术,就像工厂生产线一样,把一个指令分解成几个步骤,在不同阶段同时处理不同指令的这几个步骤,大大提高了整体吞吐量。还有乱序执行,CPU会自己找那些不依赖前一个结果的指令先执行,进一步提高效率。但这都是CPU内部的优化,一旦遇到“瓶颈”,就没法跑飞了。

2. 为什么“卡”了?罪魁祸首可能不是CPU!

既然CPU这么能打,那为啥还会卡?关键在于,程序运行不是只有CPU在干活,它是一个复杂的系统工程,CPU只是其中一个环节,而且很多时候,它根本就不是那个最慢的环节。

内存(RAM)瓶颈:
容量不足: 当你打开的程序太多,或者运行一个吃内存的大型应用(比如视频剪辑、大型游戏、虚拟机),而你的内存容量不够时,系统就会把一部分数据暂时写到硬盘上(所谓的“虚拟内存”或“页面文件”)。硬盘的速度比内存慢几个数量级,读写这些数据就会导致整个系统瞬间“窒息”,CPU在那儿等着,啥也干不了,这就是典型的“内存不足导致的卡顿”。
速度不够: 即使内存容量够,但如果内存本身的频率和延迟跟不上CPU的需求,CPU也得等着内存把数据送过来,或者把结果写回去。CPU跑得越快,对内存的要求就越高,如果内存是短板,CPU的性能就发挥不出来。

存储设备(硬盘/SSD)瓶颈:
传统硬盘(HDD): 机械硬盘的读写速度非常慢,尤其是随机读写。操作系统需要频繁地从硬盘加载程序、读取文件、写入缓存。当你打开一个程序或者进行文件操作时,如果硬盘跟不上,整个过程都会慢下来。
固态硬盘(SSD): 虽然SSD比HDD快多了,但即使是NVMe SSD,相比于内存的速度,仍然有不小的差距。而且SSD也有一定的读写延迟。更关键的是,SSD的寿命是有限的,系统也会有意识地减少不必要的写入来延长SSD寿命,这在某些情况下也可能影响响应速度。
文件碎片化/文件系统效率: 即使是SSD,如果文件系统碎片化严重,或者文件管理效率不高,也可能导致数据读取变慢。

显卡(GPU)瓶颈:
图形处理: 现在的操作系统界面越来越漂亮,特效越来越多(比如透明窗口、动画效果、高分辨率显示)。这些都依赖显卡来渲染。如果你的显卡性能不足,或者驱动程序有问题,即使CPU再快,界面都会显得不流畅,卡顿感会非常明显,尤其是在你进行窗口切换、缩放或者观看高清视频时。
游戏和3D应用: 这是显卡最直接的体现。在大型游戏里,如果显卡处理不过来,帧数就会下降,画面就像在放慢动作一样卡。

软件优化和设计问题:
低效的代码: 很多程序,尤其是老旧的或者未经良好优化的程序,可能使用了非常低效的算法或者内存管理方式。即使CPU很强,也可能因为软件本身写得不好,导致它“想做的事情”太多,或者做事情的方式太笨拙,从而拖慢整个系统。
多线程利用不充分: 尽管现代CPU核心很多,但如果软件开发者没有设计好“多线程”代码,让各个核心能够并行高效地工作,那么即使是多核CPU,很多时候也只有一个或少数几个核心在忙,其他核心却闲着。
后台进程和驱动: 操作系统背后有很多进程在运行,比如杀毒软件的实时扫描、系统更新的检查、各种软件的后台服务。如果这些进程占用了过多的CPU、内存或磁盘资源,或者某些硬件的驱动程序有问题,都可能导致前台应用出现卡顿。
线程调度: 操作系统需要负责把CPU时间分配给不同的程序和任务。如果它的调度算法不够智能,或者某些任务“霸占”了CPU太久,也可能导致其他程序感觉卡顿。

网络问题:
在线应用: 很多现代应用(比如网页浏览、在线游戏、视频会议)都高度依赖网络。如果你的网络连接不稳定、带宽不足或者延迟很高,即使你的电脑硬件再好,也会感觉卡顿,因为程序在等待网络数据的返回。

散热和功耗墙:
过热降频: 当CPU长时间高负荷运行时,会产生大量热量。为了防止损坏,CPU会自动降低运行频率(降频),来控制温度。这时,你感觉到的卡顿,实际上是CPU主动“慢下来”了,它的“亿次计算”能力也就大打折扣了。
功耗限制: 笔记本电脑或者一些设计紧凑的台式机,为了控制整体功耗和发热,可能会给CPU设定一个功耗墙。即使CPU有潜力跑得更快,也可能因为功耗限制而无法持续维持高频率,导致性能不如预期。

3. 总结一下,为啥会卡?

你可以把电脑看成是一个由CPU、内存、硬盘、显卡、网络等组成的生产流水线。CPU的“亿次计算”只是这条流水线上的一个工人的理论生产效率。

如果:

上游(输入数据)慢了(比如硬盘读写慢、网络慢),后面的工人(CPU)就得等着。
中游(内存)容量不够或速度不够,工人就算想干活,也没地方放原材料,或者原材料送不过来,也得停工。
下游(输出结果)的设备跟不上(比如显卡处理不了那么多画面),就算工人已经把活干完了,也展示不出来,用户会觉得卡。
或者生产线上的某一个工人(CPU本身)干活效率不高(软件优化差、多线程没做好),或者工人之间配合不好(线程调度问题),也会导致整体效率低下。
甚至工人因为太热了,不得不放慢速度工作(过热降频)。

所以,即使CPU每秒能做几十亿次运算,但只要其中任何一个环节出了问题,或者这个“计算任务”本身就被设计得效率低下,用户就会明显感觉到“卡”。这就像你有一个世界顶级的厨师,但他面前的食材都是坏的,或者锅碗瓢盆都非常简陋,他也很难做出顶级的菜肴来。

要解决卡顿问题,不能只盯着CPU,而是要综合分析整个系统的瓶颈在哪里,可能是内存不够,可能是硬盘太慢,可能是显卡性能不足,也可能是软件本身的问题。只有找到并解决那个最慢的环节,才能让整个系统跑得更顺畅。

网友意见

user avatar

因为大多数项目并没有把不卡顿当作目标。

你可以这样理解:不卡顿是一个功能,如果这个功能在开发项目计划与进度中没有列为目标,那么这个功能就不会被投入力量去完成。测试也不会将卡顿报告为bug,开发也接不到优化卡顿的任务单。

对于某些项目,明确把不卡顿作为开发目标的,自然就还可以优化。虽然这代价也不小,但大多数程序多多少少是有优化空间的。只不过,通常都没有必要优化罢了。

user avatar

高票说的很棒了,我来提供另一个视角吧。


现在为了便宜、方便,绝大部分程序是用脚本语言写的。

这是因为脚本语言入门简单,很容易就能雇到程序员;而公认高效的编译型语言如C、C++、Delphi,或者即地编译的Java等专业语言入门门槛很高——起码知乎上已经有很多人持续好多年的希望它们灭绝了。以至于一旦我提到C,经常就有一票人在我的评论区酸溜溜的对以汇编……


但是,python/php/js之类语言的性能是非常糟糕的。比如这个就是一个很不全面的测试:

来自: Python与C语言、Java、Nodejs、Golang进行性能测试比较 - 云+社区 - 腾讯云 (tencent.com)


可以看出,在查找质数这个测试场景下,C/Java的执行效率是python的20/17倍。


这是个什么概念呢?

现代CPU的主频大约是4~5G,它的1/20是250MHZ。


换句话说,不考虑多核因素,只算单核性能的话——你以为你在用最先进的i9?

错。你不过是在用老掉牙的、1997年上市的奔腾2代罢了。

24年前的老爷车能跑出这个效果,知足吧。


当然,奔腾2也很强了。对个人用户的常规任务来说,它完全是性能溢出。这就是python、js大行其道的根本原因——对你来说,它足够用了。


但,这也正是C/C++、Java必须继续存在的根本原因——在它们的帮助下,才能让python把i9当奔腾Ⅱ 266MHZ用,帮你处理点不需要性能的日常任务。一旦需要性能……


尤其是,为了方便、易控制,现在恨不得一切都用h5跑在浏览器里。


注意这里并不是说脚本语言是程序卡的根本原因;事实上,电脑上所有性能敏感的地方,跑的都是C/C++或者Java(甚至,由于GC造成的stop world问题,很多地方Java都是不能用的);现代的高分辨率高帧率图像的确也需要非常非常多的性能。

这里说的是:类似脚本语言替代编译型语言这样,为了方便程序员、降低开发费用而作的“负优化”特别特别的多,多到已经规模化、系统化、标准化的程度了。


此外,国内厂商,为了垄断或者别的什么原因,致力于负优化或者阉割你的系统……


举例来说,Android有个webview组件。这个东西在Android 4.4之前基于webkit,之后就是chrome内核了——这玩意儿对H5的支持还是很不错的。


但是,国内手机厂商不约而同的阉割了这个组件,故意制造不兼容。

结果就是,除非你的app自带浏览器内核,否则就别想正常运行。


为什么我说他们是故意呢?

因为最近调一个程序,丢浏览器能跑,放手机上不行;再一试手机自带浏览器,也不行——然而Google play装的chrome又行了。

于是决定看看究竟哪的问题,打开html5test.com,手机自带浏览器得分还挺高;尤其其中我们程序功能相关的特性居然也有。

那怎么不执行我们的程序呢?想了想,我尝试重新打开过去跑不过的那个应用。顺利打开。

明白了,发现你跑html5test,它就临时打开开关,让你看它特性支持的足足的;不跑,那就不给你支持。

于是继续查,看看webview能跑多少分——果然,webview得分极低,把本来支持的近80项html5特性都关掉了。

这就使得这些阉割版系统的webview组件压根没法用。除非自带浏览器内核,绕开这个玩意儿。


举例来说,国内某龙头企业的即时通讯软件,它的国内版就不得不带了个蹩脚的浏览器组件。不然很多功能就没法实现。

但这个组件使得软件变得更加臃肿;且优化水平很差,使得这玩意儿用起来总是能明显感觉到卡卡的——正常的js引擎跑Javascript,如果还能有C的性能1/20的话,这个组件可能就只能到1/23或者1/25,甚至更差。


如果你用的是海外版或者国外品牌的手机,那么可以通过控制台卸载这个组件,让它用标准的webview,流畅度就会立竿见影的提升;但如果你用的是国内版的手机……卸载这个组件只会让它崩溃、或者页面故障。

类似的,你直接从Google play装的这个软件,它就原生不带这个组件——后果嘛,那就是流畅多了。

当然,前提是你不能用国产阉割版手机系统。卡点总比用不了强。


类似的,知乎手机版也自带了一个很烂的浏览器。chromium 87内核,html5test只有469分。但这个玩意儿比起手机自带的破烂油腻UI浏览器的444分还是高了不少。

可想而知,如果不浪费你的空间、使用阉割更严重的手机自带webview的话,体验会烂到什么地步、开发测试又会不可控到什么地步。


总之,在这些“负优化”的共同努力下,你的电脑经常要发着i9的热,享用着奔腾Ⅱ的性能……如此一来,你不卡,谁卡?

user avatar

2000年的时候,做一个PS2的儿童组合游戏,画面肯定是儿童风格的,用到的图片非常多,造成占用空间巨大。

怎么办?压缩呗。搬来几种现成的压缩轮子,JPG压缩,ARA压缩,ZIP压缩……,效果明显,压缩比十几倍以上吧,但是占用空间还是比较大,光图片都上百M,现在看100M简直是洒洒水,小意思。但在当时算是巨无霸了。(SONY先后来了两个大牛,无功而返)。

我每天对着图片库也是焦头乱额,被逼无奈只有自己来想怎么压缩,发现这些儿童风格的图片有一个共性,就是都有成片的RGB值相同的色块。然后花了一个晚上,敲了个简易的压缩程序,仅仅几百行代码而已。算法很简单,就是找到色块边缘,记录下来,并记录分块后每块的RGB值,解压过程相反,相当于先把边缘描出来,然后再填颜色。测试后效果惊人,绝大部分图片压缩比在200以上。

很惊喜,电脑上花几天时间测试完善。

然后上PS2模拟,结果发现偶尔会卡,分析比较后,就是解压缩太耗时,然后对算法优化优化优化,折腾半个多月,基本白干。算法的小细节优化,根本省不了多少时间。

后来只有搞新的算法,简化压缩流程,不寻找图片边缘了,把整个图片看成一个像素流,遇到像素RGB 变化的,记录位置,后边连续相同像素的数量和RGB值,简单暴力,比第一个算法容易太多了,结果压缩比基本上接近100,还算不错。

这次先在电脑上测解压速度,跟之前的自研算法和JPG等解压快的都不在一个数量级,解压时间基本可以忽略。

啰嗦这个事,好像跟题主问题无关。但事实上这个事说明了:

软件开发者永远在省事和能用的边缘不停试探。

软件开发者永远在省事和能用的边缘不停试探。

软件开发者永远在省事和能用的边缘不停试探。

所以,不管硬件的速度在未来快到何种程度,永远都会有程序比较卡。

假设某一天,硬件速度到了极限,无法提升了,反而会发现你常用的软件都不卡了,这是什么鬼逻辑?自己好好想。

user avatar

因为写高效率的程序不挣钱。

在计算能力匮乏的年代,银行和一些政府机构的业务程序是用cobol写的。

一些冷门业务,譬如缴费之类的业务。你交钱,录入记账,打印回单,定期打印报表,你可以查询记账,再有一些用户管理,系统管理功能的程序。

一台性能相当于iPhone4s性能的服务器,就可以负载一个城市的业务,带一个营业大厅的几十台终端。

整套系统,一个小U盘就可以带走。

后来,同样的业务功能,在windows下开发,用微软这套东西,有图形界面,就需要比较强大的服务器了。

现在,程序员开发一个人缴费的APP,占用的储存空间和内存已经比当年管理一个城市缴费的系统更大了。

现在的程序员能不能用高效率的工具写高效率的程序呢?

当然能。

在PC程序膨胀的时候,功能手机也需要写程序,当时手机硬件羸弱。

于是我们看到了诺基亚上只有几十K的QQ,已经有完整的核心功能。

后来智能手机出现,手机性能上去了,手机APP就开始放飞自我了。

早期,安卓手机不流畅,厂商还做一些优化。安卓下WPS的6.2版本,还能秒开。

后来手机硬件上去了,厂商给APP加功能,窃取隐私。程序员不做性能优化,时间长了,优化的经验也没了。即使要写高效的程序也很难了,况且老板也不要求效率,先跑起来再说。

结果就是现在的样子。国外开发APP能好一点。

结果,用户的手机,很快就被臃肿的APP拖垮了,不得不换新手机。

而手机APP很多是不升级不让你用,逼迫客户升级无用的功能。这样用户不得不换。

相比之下电脑好很多。

电脑的程序不依赖升级和网络就能用,我办公打字,只要求所见即所得。

用winxp加office2003,能一直用到硬件报废为止。所以,我们现在能看到一些地方用十几年,二十年历史的电脑在工作。

软件低效的问题,只能政府管。

政府不允许低效软件上线。规定低配置手机跑流畅的APP才能审批上应用市场。

程序员和老板自然就要求优化了。

user avatar

因为在等待外设的响应。

比方说,CPU从磁盘中读取一个文件。虽然现代CPU每秒数亿次计算,但是磁盘每秒钟却读不出来数亿M的数据。对不起,请CPU等一下。

比方说,我在上海从我的电脑发一个文件给北京的电脑。虽然现代CPU每秒数亿次计算,但是网络却没有这么快。

即使是执行一个简单的计算程序,因为现在的操作系统是支持同时执行多个程序的。因此上需要另外一个之前执行的程序使用的内存中,对于前一个程序有用的信息先放到磁盘上,之后才能跑你的程序。专业术语叫磁盘交换。

至于手机上的APP。这个是JAVA虚拟机的锅。你的每一个操作都是先转换成JAVA虚拟机指令,由虚拟机指令转换成CPU指令执行。

user avatar

之前PC界有个Wintel联盟:微软和英特尔。

英特尔负责设计更快的CPU,微软负责把CPU升级的部分用完。争取让用户每3-5年升级一下电脑。

后来不仅仅是CPU,显卡、内存、总线的升级,都要占用。以至于对于部分(如果不是大部分)用户来说,隔几年升级不过是为了让电脑在新的系统下,看起来不是那么慢而已。

这是一种阳谋。

如果一台计算机(现在的智能手机也是计算机)买过来就能用10年甚至更长时间,估计硬件公司和软件公司就快饿死了。

这和历史上电灯泡生产厂家,故意把电灯泡的寿命从10年缩短为3年没有区别(后来缩短成一年?)。

在这个商业模式里,最优秀的程序员也只是帮凶而已。

而那些不那么优秀的程序员,则变成了被嘲讽的对象。

愚蠢的程序员,则成了这个话题的躺枪者。

比如,到现在竟然还有在两个只有不到1000条数据表进行联合查询,就会导致界面失去响应的大侠。

user avatar

好几个原因

第一个原因,他们没做硬件加速渲染,也就是对于图像的处理,需要交给gpu完成,光cpu很难达到理想的效果,这个在做动画的时候,眼睛会比较明显能感觉得到

这个比较典型的例子就是java的swing,缺省是不会做硬件加速渲染的,除非你手动打开opengl,而且如果你的机器上不支持opengl的话,那么用的是java2d,也就是纯软件渲染,会很明显滴感觉到卡顿

值得说明的是,这不是说你换c什么就能解决的,如果你用c也是纯软件渲染的话,一样慢

所以一般都是对opengl,vulkan,metal等硬件加速渲染的渲染管道api做封装,然后再将其包装成对应语言的api,然后通过调用这些api,来调用硬件加速渲染的管道以处理图像

cpu的优势是整形计算,gpu都是浮点型运算嘛,图像其实都是浮点型计算,cpu的强大算力对于图像处理帮助有限

第二个原因,没有做aot,没有编译成native,机器码,所以程序在执行的时候,经常会经过几个步骤,就先将源代码或者字节码之类的,编译成机器码,然后再执行,这样做的好处就是方便你跨平台,因为你编译成机器码之后,生成的这个机器码是没有办法直接交给其他平台去执行的

只能是能够执行该机器码的平台才能执行,比如你针对windows编译了windows可以执行的机器码,那么该机器码拿到linux上去,就无法执行了

但是如果你生成的不是机器码,而是字节码,甚至源代码,那么你就可以在不同的平台上执行

把源代码编译成机器码,这个现在叫做aot,如果不编译成机器码,以能够跨平台的一种命令形式存在的话,这个叫做jit,just in time compilation,aot和jit的对比,各有优劣,但是简单说,就是aot的产物,启动更快,内存使用更少,这个对于一个客户端程序而言,启动快慢会让你有一个直观的感受,如果启动快,你可能就会觉得快了,虽然执行一段时间之后,jit并不会比aot慢,甚至会更快一丢丢,但是第一影响一旦形成,后续你就比较难以扭转,哪怕后面jit可能会更快一点,但是你也未必会有这种感觉

那现在很多程序,是没有做aot的,尤其是web上用所谓的跨端技术搞出来的东西,很多都是脚本套个浏览器就到处用,这样做能不慢么?

不过好的地方就是,现在谷歌,java,苹果,都在做aot,纷纷推出aot技术,像苹果,会对你上架app store的app要求编译成native,google play也会在你下载的时候,对app做native编译,所以从目前大趋势看,客户端还是越来越多要求做aot编译的,至少你在发布时候,一般都会做aot,能做的话,都会做aot,这个趋势应该很明显,做了aot之后,客户用的程序多少都能感觉到快一点

第三个原因可能是gc带来的,gc要想写好,并不容易,真正能把gc做好的技术并不多,像swift,依旧没有特别省心的gc技术,要用arc,一定程度上增加了程序员的心智负担,实测发现,几年前,市场上常规的gc,都还在100ms上下,现在经过各种优化,尤其是1ms以内的zgc正式下发生产之后,我们有理由相信,以后gc带来的卡顿问题会越来越少

第四个,额外操作,有些程序,并不是你表面上看上去的那么简单,不多解释,你懂的

第五个,代码写得比较糟糕,但是跟前面几个比起来,我觉得一般程序员代码写得糟糕带来的影响,可能没有前面几个造成的影响大,当然不可否认,如果代码写得不好,也有可能造成卡顿的后果

user avatar

因为现在的程序员图省事懒得优化了,反正「CPU 很快」。

user avatar

计算机产业中有个很著名的安迪-比尔定律,重要性不在摩尔定律之下。

大家都知道摩尔定律:硬件性能每18个月就会翻一番。虽然随着CPU制程接近极限,最近几年摩尔定律基本失效了,但是硬件性能的上涨依然很快。现在的CPU比起四五年前的CPU肯定是快了一倍以上,但是我们并没有感觉到软件运行也快一倍。

安迪-比尔定律是这么说的:安迪给予的,比尔都会拿走。安迪是Intel的前CEO,而比尔是微软的前CEO。这条定律的意思是说硬件增加的性能都会很快的被软件消耗掉。基本上,最新的软件总是会尽可能的榨干硬件能提供的全部性能资源。

其实,软件开发过程中免不了各种“优化”,就是对想要干的事情进行一些简化,以保证硬件性能能够匹配。在Windows系统出现之前,软件只通过简单的文字来展示界面,后来出现了图形界面、高清图标。显示器分辨率从640*480发展到3840*2160,所需的系统资源是指数级提升的。想要模拟的东西也越来越接近真实世界。

其次,软件开发中有一些原本由程序员人工确定的部分,现在也逐渐变成由软件自动实现。比如在前端开发中,以前我们要逐一确定界面上发生修改的元素,并用代码逐一将这些元素更新。现在我们只需提交更新后的界面描述,软件自己将会比对新界面和老界面之间的区别,然后将产生变化的元素更新。这极大的简化了程序员的开发工作,但是却也消耗了一些性能。

虽然现在硬件发展的很厉害了,但是软件想要的野心更大,现在无法由计算机实现,仍然需要简化的部分在软件开发中还有许多。虽然摩尔定律基本失效了,但是安迪-比尔定律应该会继续有效下去很长时间。

user avatar

这不关 CPU 的事。

如果一个应用程序打开慢,在硬件条件还可以的情况下,那么大概率是这个应用程序里藏着“shi山”一般的代码,让 CPU 做了非常多的无用功,就好像备胎再怎么努力怎么舔女神,终究都不会有好果汁吃。

我之前就看过这么一个有趣事情。

GTA 5联机版这款游戏都发行了长达 7 年之久,但是还是打开那么慢,进游戏少则等5、6分钟,多则20分钟,引发了无数玩家吐槽抱怨……

终于有一天,一个黑客大哥实在忍不了,用「逆编译器」逐条查看运行情况,终于找到原因。

原来,R星(游戏开发商RockStar)写的代码太低效,加载时,一个if语句竟然循环了19.8亿次…,也就是说推卸了一堆 shi 一样的代码,能不慢才怪!

贾浩楠 发自 凹非寺
量子位 报道 | 公众号 QbitAI
参考资料:量子位:GTA5要跑19.8亿次if!黑客修改后直接省70%加载时间

幕后黑手:谁占用大量时间?

加载GTA 5 Online到底有多慢?

硬件拉满的土豪玩家请无视

Reddit相关板块发起的调查中,超过80%的玩家,都要等3分钟以上,有的甚至超过15分钟。

而且,从7年前Online上线到今天,这个情况丝毫没有改善。

暴躁的,已经骂起了脏话……

但奇怪的是,如果你选择是故事模式(单机版),加载就会快很多,感觉甚至像两个不同的工作室开发的游戏。

具体到这位黑客大哥的例子,他自己的硬件配置如下:

CPU,是老而弥坚的AMD FX-8350,2012年上市,采用“推土机”架构,超频潜力惊人。

显卡还是GTX 1070。

这样今天看起来老旧的配置,打开单机版GTA 5需要1分10秒,而加载联机版则6分钟起。

黑客大哥用了最简单的Windows任务管理器,来判断联机版GTA 5在启动时,都调用了哪些计算机资源。

在1分钟的时间分界线上,之前是加载的是单机和联机版通用的基础内容,之后是联机版独有的内容。

可以看到,联机版GTA 5,加载时调用大量CPU资源至少长达4分钟之久。

而同时,内存、GPU、硬盘的使用情况几乎没有明显变化。

所以,问题大概率出在代码上。

插个题外话。

小林在知乎写了很多图解网络和操作系统的系列文章,期间收获到很多知乎朋友的认可和支持,正好最近图解网络和操作系统的文章连载的有 20+ 篇了,也算有个体系了。

所以为了方便知乎的朋友们阅读,小林把自己原创的图解网络和图解操作系统整理成了 PDF,一整理后,没想到每个图解都输出了 15 万字 + 500 张图,质量也是杠杠的,有很多朋友特地私信我,看了我的图解拿到了大厂的offer。

现在图解网络和图解系统 PDF 开源给大家:

好了,继续说 GTA 游戏的事情。

“R星代码写太烂!”

黑客大哥在开扒R星代码之前,就说:

我闻到一股烂代码的味道…..

为了找出到底那一部分程序卡住了CPU,他使用了工具Luke Stackwalker,对CPU任务堆栈进行采样分析。

Luke Stackwalker对于闭源应用程序,可以转存正在运行的进程堆栈,和当前指令指针的位置,以一定时间间隔建立一个调用树。

最后将数据整合,就可以得到程序运行统计数据。

从结果上看,一共有两个函数“卡住”了CPU:

于是他使用专业的代码拆解工具,给GTA 5来了一个“开膛破肚”。

沿着调用栈往下走,发现问题出在一个sscanf函数上。

sscanf的功能是读取格式化的字符串中的数据,而在GTA 5中,它正在读取的是一个10M左右,有63000多个条目的JSON文件。

这个文件到底是干什么用的?黑客大哥推测,这可能是游戏内购商店的相关内容。

在具体运行时,sscanf对于每个有效值,逐个读取每一个字符,然后返回结果,之后指针移向下一个值,循环往复……直到把10M文件全部扫一遍。

再看第二个问题,这是一个存储命令,对象是item,具体是什么不得而知。

但是保存前,有一个if语句,逐一比较item内项目的哈希值,检查它们是否出现在某一列表中。

按照他的计算,这一步if,要执行(63000^2+63000)/2 = 1984531500次!

没错,等待加载前的十多分钟里,GTA 5用你的CPU,执行了19.8亿次if命令。

如此简单粗暴的编程思路,让这位老哥哭笑不得:

既然对象有唯一哈希值,那为什么不用hash map???

(hashmap根据hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序不确定。)

问题解决,加载时间节省70%

至于第一个问题,黑客大哥采用hook大法,不一一读取字符串,而是:

hook strlen
“缓存 “字符串起始和当前长度。
如果在字符串范围内函数在此被调用,返回缓存的值

至于if语句问题,就更直接了——完全跳过重复检查,利用hash map插入项目,因为这些值是唯一的。

最后的结果如下:

现在,GTA 5联机版加载,从原来的6分钟,下降到现在的1分50秒!而且,用的还是七八年前的硬件配置。

在此,应该手动@R星:你学废了吗?

user avatar

数亿次够干啥的?

以专业图形渲染为例(区别于使用GPU的游戏渲染)

假设你要渲染1080p的画面,这就是1080*1920两百万个像素。

每个像素都要路径追踪得到应有的颜色,比如假设有1000条光线射到这个像素点,取平均才能得到应有的颜色。

然后这每一条光线简单起见经过一次反射就能从光源射到这个像素。

每一次反射要计算很多信息,以计算反射角的三角函数为例,假设用三阶展开简化计算,这就得十几次乘法。

每次乘法都是对于64位浮点数*64位浮点数计算。

你算算这一帧都多少次计算了?

user avatar

2021.11.19 更新,最近还是有人点赞,有点小离谱,这问题生命力真强。

作为彩 大龄程序员,给后辈一个建议,就是多学,但是学精就算了,我等悟性学不精,学得精也很难遇到精密要求自己的自己和要求自己的岗位/公司。多学新东西,就可以去新公司混/或者混到新兴岗位上。

目前我在用xamarin搞app 应用。搞得屎一样,好在用户量很少,企业内部用用,也能对付。算是独立开发者,比较自由。可以决定自由的时间是用来学习/游戏/股票。就是觉悟得太晚了。现在房价都不怎么涨,后辈如果现在收入不错,赶紧开始理财吧,不要像我这么大年纪才开始搞。

不要脸的说一句,咱们在搞程序里面的,不见得算脑子好用的,但是在搞股票的里面,咱们一定是好用的,程序员不要内卷了,去买股票吧。我今年3月份开始炒股收益率都40%多了。


一天下来,惊呆了,这么多赞,看来获赞的主要原因还是达成共鸣了。

我干程序员也差不多10年了.小学就接触了一些VB,后来工作就发现,很多时候确实工作上很难都高标准要求自己.所以很佩服那些业余时间还会自己做做项目的人. 自己经常项目初期搭个讲究的框架,到开发中期,发现原来设计有点不合理.开始重构,然后一天过去发现业务功能非但没有增加,甚至还制造了更多待优化的项目. 随着时间推移,项目进度就更紧张了.越往后就越随意,再往后就是破窗效应了.一旦你容忍了几个自己项目的白痴代码,接下来就开始放飞自我了. 这就有点像我刚追女朋友的时候,我每天早期刷牙洗脸刮胡子.到同居后,我就要女朋友逼我洗澡了... 现在十几年职业生涯过去.发现所有的技术进步无非集中在:

  • 经验积累,掌握了更多更快的更容易维护开发的手段.虽然这些手段的性能不见得更好.
  • 即使程序未必比过去跑得快,但是程序出问题的时候的bug比过去容易显示了.
  • 进入职业的中期,深感老板也不在乎的技术,他们脑子都是业务,而你做出自己有成就感的设计提高开发效率的成就感在老板那边甚至你无法和他分享快乐. 最后逼着自己向老板兜售业务.
  • 所有的技能居然都来自新业务. 比如搞xamarin 因为我需要做ios了.仅此而已.

知乎上很多微软 谷歌 BAT 的大牛.他们看看着很潇洒的完成工作. 业余还能发发知乎,带大家逛,甚至做几个牛逼的轮子让大家瞻仰,但是我知道更多的程序员都是我这样平平无奇的人,在大牛眼中可能只是码农码畜,把网络上复制的代码组合加点业务就是我们的工作写照了.但这真的是多数程序员的工作, 没成就更无聊.

看到评论大家开心的血压拉满,能给大家带来一点快乐. 或许是我给程序员们带来过的最大价值了.


我这样拉跨程序员写的程序经常这样:

  • 不做异步,就在UI线程上搞事情.任何事做完之前.程序都是卡的
  • 不做并行,不管你是多少核cpu.我只有单线程
  • 使用网络资源的时候,不处理UI.甚至就干等,如果网络不稳定.程序就卡住,其实CPU根本没干活
  • 写很多大量无效的类型转换/装箱拆箱,声明使用一大堆集合
  • 为了重用代码,同时也懒得优化代码,一件简单的事情,交给一个很复杂的模块处理,说人话就是, 你需要一个螺母,你不直接买一个螺母,你买了一辆汽车,然后把螺母拆下来用,下次我需要一个螺丝,我甚至不用之前买的那辆汽车的螺丝,我再买一辆新的....
  • 不管用不用得着,总是使用原始的高清资源.比如用户头像.贪方便.我直接用1080P的图也不压缩...
  • 不缓存任何资源,哪怕一个东西反复被使用,依然不停从数据源获取数据...
  • 使用完数据不释放.... 比如我买了车取下它的螺母用,但是我车也不处理掉,还放在那做摆设.
  • 因为懒得写合理的数据传递.明明要用参数传递的数据一股脑放在全局变量. 拿生活做比喻就是我明明只是和你发私信,但是因为懒得写收件人信息,直接登人民日报...
  • 我们拉跨程序员多半知道写的东西垃圾在哪里,他们只是不知道这垃圾啥时候会在实际运行中爆发出问题来.偶尔也不知道这些垃圾组合在一起为啥居然可以运行,更不不知道这些垃圾组合在一起产生哪些新的特性.

哦.最重要的,我们拉跨程序员不觉得卡是bug.我们只觉得报错/崩溃/错误的数据展示是BUG...

user avatar

真正CPU运算能力不足导致的卡的场景其实只占不到10%。

导致卡的最大的两个原因是锁和IO,简单说就是和CPU没啥关系……

类似的话题

  • 回答
    你这个问题问得特别好,而且也戳到了很多人的痛点。明明咱电脑里的CPU都说每秒能跑多少亿次浮点运算,号称“高达xxx GHz”,听着就挺牛的,但为啥实际用起来,打开个软件、切换个窗口,就感觉它卡卡的,响应迟缓,甚至卡成PPT呢?这背后其实是挺多门道,不只是CPU性能高低那么简单。咱们就掰开了揉碎了聊聊.............
  • 回答
    这确实是个让人头疼的问题,很多玩家都感觉自己的高端多核CPU在玩游戏时“大材小用”,明明有八核甚至更多,游戏里却感觉只有两三个核心在拼命干活。为什么会这样呢?这背后其实涉及很多层面的原因,而且一点也不神秘,而是跟整个游戏开发流程、技术限制,甚至是历史遗留问题都有关系。1. 游戏设计与开发模式的“单线.............
  • 回答
    你这个问题提得特别好,直击要害!现在手机市场竞争这么激烈,大家买手机确实越来越看重CPU和GPU了,这背后可不是空穴来风,而是有一系列原因在共同作用。我跟你好好掰扯掰扯,争取让你听明白了,也尽量不整得跟机器写的一样。首先,得承认,现在手机的功能已经大大超越了最初的通讯工具。我们不光打电话发短信,刷短.............
  • 回答
    过去的电脑处理任务,尤其是那些需要大量计算的工作,主要依赖于中央处理器,也就是我们常说的 CPU。CPU 就像是电脑的大脑,它设计得非常精巧,擅长处理各种复杂、顺序性的指令,比如运行操作系统、处理文字、浏览网页这些需要逻辑判断和精细操作的任务。一个 CPU 里面会有几个核心,每个核心都像是一个小型的.............
  • 回答
    AMD,这个名字在PC硬件圈子里,从早期欣欣向荣,到后来的几经沉浮,再到如今的王者归来,其生存之道,绝非一日之功,也绝非单一因素能够概括。如果你觉得它似乎总在NVIDIA和Intel的阴影下,那是一种观察的视角,但它能走到今天,并且还能让你觉得它有“生存”的意义,这本身就说明了它的顽强和聪明。咱们不.............
  • 回答
    超线程:逻辑与现实的博弈,未来何去何从?在x86架构CPU的性能竞赛中,“超线程”(HyperThreading)无疑是一个绕不开的话题。它犹如给每个物理核心插上了翅膀,让一个核心同时处理多个线程成为可能,从根本上提升了CPU的并发处理能力。长期以来,我们习惯了超线程将逻辑处理器的数量翻倍,也就是一.............
  • 回答
    关于多核CPU上多线程排序遇到的奇怪现象,这绝对是个值得深入探讨的问题,毕竟并行处理的设计初衷是为了提升效率,但有时候却会“事与愿违”。咱们抛开那些AI味的列表和框架,就像朋友聊天一样,一步步剖析一下可能的原因。首先,得明白,多线程排序,尤其是你感觉到的“奇怪现象”,往往不是因为CPU本身出了什么故.............
  • 回答
    知乎的各位大佬们大家好!关于AMD 3400G搭配独显后的CPU性能问题,以及在寝室限功率环境下作为过渡方案的详细分析,我来给大家说一说。核心问题:AMD 3400G 搭配独显相当于什么CPU的水平?首先,要明白一点:APU(Accelerated Processing Unit)的CPU部分和独立.............
  • 回答
    现代社会分工明确、效率提升,这无疑是人类文明进步的重要标志,带来了前所未有的物质丰富和生活便利。然而,与此同时,许多人却感到生活压力不断增大,这种现象背后有着复杂且相互关联的原因。下面我将尽量详细地阐述:一、 分工明确与效率提升带来的直接影响(积极面与潜在负面) 专业化带来的知识与技能壁垒: .............
  • 回答
    现代西方经济学之所以抛弃了劳动价值论,是一个复杂而渐进的过程,涉及理论上的不足、实证上的挑战以及新经济思想的兴起。要详细解释这一点,我们需要回顾劳动价值论的核心思想、其面临的困境,以及最终被其他理论所取代的原因。劳动价值论的核心思想:劳动价值论是古典经济学(尤其是亚当·斯密和大卫·李嘉图)和马克思经.............
  • 回答
    这是一个非常有趣且值得深入探讨的问题。现代作家写作条件确实比过去优越得多,但“震撼人心”的作品似乎不如过去那样普遍。这个问题并非绝对,肯定存在一些优秀的现代作品,但如果我们感受到的是一种“普遍缺乏”,那么我们可以从多个角度来分析原因。以下是一些可能导致这一现象的因素,我会尽量详细地阐述: 1. 写作.............
  • 回答
    在聊现代宗族概念为什么淡化之前,咱们得先掰扯掰扯,这“宗族”到底是个啥玩意儿。你要是问我,我肯定说,宗族啊,它不仅仅是几个人姓同一个姓,聚在一起过年过节吃顿饭那么简单。它是一种非常强大的社会组织形式,一种纽带,连接着过去的祖先、现在的一家人,还有未来的子孙后代。在古代,尤其是在中国这样的农耕社会,宗.............
  • 回答
    在咱们这个时代,说实话,律师这个职业,跟别的行当比起来,总觉得有那么点儿不一样的味道。不是说他们好或不好,而是大家伙儿心里那杆秤,似乎对律师总是多几分审视,带着点儿复杂的情感。这可不是一朝一夕形成的,背后门道儿可多着呢。首先,得从“权力的守护者”和“规则的执行者”这个双重身份说起。咱们常说,法律是社.............
  • 回答
    在讨论“汉奸”这个概念之前,我们得先明白它在不同语境下的含义。在历史语境下,尤其是在抗日战争时期,它通常指那些在日本侵略者统治下充当走狗、出卖国家和民族利益的中国人。而放在当今中国社会,“汉奸”的用法就更加复杂和敏感,并且很大程度上是一种道德批判和政治标签,背后折射出的是当下社会的一些深层情绪和认知.............
  • 回答
    现代军用运输机之所以不再采用活塞发动机,这背后是一个技术演进、效率提升以及战场需求不断变化的历史过程。简而言之,活塞发动机在很多关键性能上已经无法满足现代军事运输的严苛要求了。我们得先回想一下活塞发动机的辉煌年代。在第二次世界大战期间以及之前,活塞发动机是航空动力的绝对主力。无论是侦察机、战斗机还是.............
  • 回答
    这个问题很有意思,它触及了生物进化、生态环境以及古生物学的一系列复杂因素。我们之所以能看到蓝鲸这样庞然大物出现在我们这个时代,绝不是偶然,而是多种有利条件的长期累积和共同作用的结果。要理解这一点,我们可以从几个关键的维度来拆解:1. 漫长的进化史与祖先的启示首先得承认,蓝鲸的巨大并非一蹴而就。它们的.............
  • 回答
    现代都市传说之所以普遍偏向恐怖,与古代传说存在显著差异,这背后是一个复杂且多层面的社会文化演变过程。我们可以从多个维度来深入探讨这个问题:一、 社会环境的变迁与心理需求的差异: 古代社会: 生存压力与直接威胁: 古代社会,人们面临的威胁更加直接且具象化,如饥荒、疾病、战争、自然灾害、.............
  • 回答
    现代军舰之所以如此昂贵,动辄上十亿甚至几十亿元人民币,是一个多维度因素共同作用的结果。这背后不仅仅是钢铁、螺丝和船体本身的价格,更包含了尖端科技、复杂系统集成、人员培养、长期维护以及国家战略安全需求等多方面的沉淀。下面我将尽量详细地阐述这些原因:一、 尖端科技的集成与应用:这是现代军舰造价高昂最核心.............
  • 回答
    现代榴弹炮之所以普遍不采用左轮旋转供弹这种设计,主要有以下几个原因,这些原因与榴弹炮的作战需求、技术可行性、以及整体性能考量息息相关。下面我将尽量详细地阐述:1. 供弹速度与持续射击能力的限制: 左轮的射速限制: 左轮手枪之所以采用旋转供弹,是因为其弹膛容量相对较小,且击发后需要旋转才能将下一发.............
  • 回答
    这个问题问得很好,而且触及了现代育种策略的核心。很多人都有类似的疑问:为什么我们不去充分挖掘大自然已经慷慨给予的丰富变异呢?非要费那么大劲搞什么“转基因”,这背后究竟是怎么考量的?首先,咱们得承认,大自然确实是个神奇的“实验室”,在漫长的演化过程中,它产生了令人难以置信的遗传多样性。想象一下,在全球.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有