当前位置:首页 > 引流 > 正文内容

C语言给二维数组赋值变量 判断c语言二维数组的赋值

admin3年前 (2022-10-21)引流794

学习C语言最有效的方法就是多做实验,很多第一次开始学的人深知这一点。小明在学到二维数组时,尝试写了一段给二维数组赋值的代码,他发现一个奇怪的现象:交换赋值顺序,效率是不同的。

交换赋值顺序,效率是不同的

请看下面这两段C语言代码:

版本 1int test1 (){ int i,j; static int x[4000][4000]; for (i = 0; i < 4000; i++) { for (j = 0; j < 4000; j++) { x[j][i] = i + j; } } return 0;}版本 2int test2 (){ int i,j; static int x[4000][4000]; for (j = 0; j < 4000; j++) { for (i = 0; i < 4000; i++) { x[j][i] = i + j; } } return 0;}

唯一的不同点在于交换了 i 和 j 变量

这两个版本的C语言代码几乎完全相同,唯一的不同点在于交换了 i 和 j 变量,但是编译成C语言程序执行后,消耗的期间却是不同的,这是怎么回事呢?

解析 可能有访客认为这两段C语言代码产生效率上的差异,是因为编译器处理这两段代码时,产生的指令不同。其实不是的,这两段“对称”的C语言代码产生的指令是一致的,请看:

test1() 函数对应的汇编代码

上图是 test1() 函数对应的汇编代码,下图是 test2() 函数对应的汇编代码。

test2() 函数对应的汇编代码

仔细对比 test1() 和 test2() 对应的指令,咱们很难发现二者有什么不同。事实上,二者运行的效率差异主要来自于“缓存命中率”。简单来探讨,就是连续操作C语言中的多维数组的最后一个维度最快,因此 test1() 中的赋值操作几乎每次都会错过缓存,而 test2() 中的赋值操作缓存命中率更高一些,因此 test2() 执行所消耗的期间更少。

在很多C语言第一次开始学的人的脑海里,二维数组各个元素在内存中的分布可能是下面这样的:

二维数组各个元素在内存中的分布

但是计算机中的内存地址始终是一维的,因此在计算机眼中,二维数组仍然是遵从一维排列的:

二维数组仍然是遵从一维排列的

test2() 中的赋值操作先遍历第二维,这一过程是下图这样的:

这一过程是下图这样的

此时C语言程序每次访问数组元素,在内存中都是顺序进行的,这对于缓存命中率的提升很有帮助。接下来看 test1() 中的赋值操作,它优先遍历第一维,因此访问数组元素的过程是下图这样的:

访问数组元素的过程是下图这样的

显然,此时C语言程序访问数组元素在内存中是“跳跃式”的,但是,计算机访问内存各个地址的效率不是都一样的吗?那为什么 test1() 和 test2() 的效率不同呢?

答案就是 test1() 和 test2() 的缓存命中率不同。计算机 cpu 一般都有更加高速的缓存(称为“缓存线(cache line)”,常是 64 字节),访问这一缓存的速度比访问内存的速度要高的多(访客可以对比想象计算机访问内存的速度比访问硬盘数据的速度快得多)。

小明的C语言代码中赋值的元素是 int 型的(常常是 4 字节),因此 64 字节的缓存线可以容纳 16 个连续的整数,CPU 访问这 16 个数据要比访问内存里的 16 个数据快得多,并且 CPU 在加载缓存线数据的期间内,能处理相当多的工作。

CPU 在加载缓存线数据的期间内,能处理相当多的工作

CPU 在处理 test2() 中的赋值时,可以获取 16 个连续的整数块,然后赋值给数组,重复 4000*4000/16次,这样的操作在缓存线的支持下相当快,因为 CPU 没有被闲置,总是在处理事务。

再考虑 test1() 中的赋值,缓存线加载了 16 个整数块,但是接着值改写了其中一个整数,因此它需要重复 4000*4000 次,相比于 test2() 中的赋值,需要 16 倍的内存“回迁”次数。而 CPU 说实话需要花期间坐着干等内存操作完成,因此 test1() 的效率要低一些。

小结 本节主要讨论了一个看似“灵异”的C语言二维数组赋值问题,这无关指令差异,更多的是缓存命中差异带来的效率差异。但是访客应该明白,并不是所有的计算机程序都如此,例如 Fortran 语言中,test1() 中的赋值效率要高于 test2() 中的赋值效率,因为它将二维数组在内存中展开时,是遵从“列”优先排列的(C语言是按“行”优先排列的)。

扫描二维码推送至手机访问。

版权声明:本文中部分文字、图片、音频、视频来源于互联网及公开渠道,仅供学习参考,版权归原创者所有! 如侵犯到您的权益,请及时通知我们!我们将在第一时间内删除。

本文链接:http://www.73ya.com/yinliu/6044.html

分享给朋友:

“C语言给二维数组赋值变量 判断c语言二维数组的赋值” 的相关文章

抖音号能够提供哪些信息 知道抖音号能干什么

现在大家几乎都会在抖音上注册一个账号,那么抖音号有什么用呢?今天我们就一起来看看关于抖音号能够提供哪些信息,知道抖音号能干什么的相关内容。 抖音号能够提供哪些信息 现在如果申请一个抖音号的话,他是必须要绑定一张手机卡,一个...

短视频素材哪里找 玩短视频剪辑哪里找素材

随着短视频的发展,各大手机端剪辑app的出现,降低了短视频的门槛,而短时频的高收益也吸引了越来越多的自媒体人入局,从目前各项数据来看,短视频从业者已经远远超过了图文创作者。如今各大手机剪辑工具的出现,使得视频剪辑越来越简单便捷,即使零基础也能学会,但是对于独自一人做短视频的小伙伴来说,最...

抖音短视频平台怎么赚钱的 抖音视频平台如何赚钱

现在的抖音很多普通人都想在上面赚钱,看似简单,其实想要在抖音上赚钱也是要具备一定能力的。如果听别人随便说一下你能赚钱,你能赚钱,这种话,你可能会在抖音上面面临九死一生,当然说九死一生有些夸张,意思就是你会被很多人收割,现在抖音平台也有很多骗子,专门骗新人小白入局抖音,所以如果你没有以下的...

2022年全新的视频素材网站有哪些,十个网站够你用了

很多的短视频原材料在视频后期制作中是必不可少的,相信很多朋友都知道制作一个完美优秀的短视频都需要优秀的素材来加持。没有高质量的素材也打造不出来一个优秀的作品,那么有些找素材的网站大家都找烂了吧,那么接下来就跟着小编一起来看看2022年全新的视频素材网站有哪些吧。 2022年全新的视频素...

如何快速学习短视频,发布视频有哪些小技巧

在面对短视频自媒体时代,越来越多的人抓住这个机遇,觉得短视频不仅可以成为一个副业,也能为自己带来乐趣,不仅如此,做的好的话也能拥有高收入,那么如何快速的学习短视频呢?接下来就跟着小编一起来看看吧。 如何快速学习短视频 1.创作领域 首先要明白你短视频创作的领域。比如美食领域,做美食或者...

广西旅游最好的地方(广西最值得去的地方推荐)

广西中老年人必去的景点,是适合开展长寿之乡观光考察和长寿养身度假旅游的长寿河风景区。除此之外,广西中老年人游玩好去处还有龙胜温泉旅游度假区、漓江风景名胜区、金钟山旅游度假区、青秀山、广西药用植物园等。 1、长寿河风景区 长寿河风景区也叫盘阳河风景区,是开展长寿之乡观光考察和长寿养身度假...