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

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

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

学习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://73ya.com/yinliu/6044.html

分享给朋友:

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

抖音如何使用本地音乐 抖音上怎么使用本地音乐

我们除了在抖音添加在线的音乐外,本地音乐应该如何添加呢?今天我们就一起来看看关于抖音如何使用本地音乐,抖音上怎么使用本地音乐的相关内容。 抖音如何使用本地音乐 1) 首先我们在应用市场找到"清爽视频编辑"这款主流视频编辑软件,然后点击主界...

如何成为一个优质的短视频作者,新人也能轻松涨粉

短视频每天都有人入行,这也就意味着短视频平台的竞争力度很大。我们想要在短视频的平台上站稳脚跟,就必须有属于我们自己的色彩。而你做为一个新人来说,如何成为一个优质的短视频作者?接下来就跟着小编一起来看看吧。 如何成为一个优质的短视频作者 01 新人成长的第一步 作为一个短视频的新人小白...

新人怎么做快手直播,视频直播怎么预热

新人在直播前发布预热短视频是非常重要的,主播拍摄的直播预热短视频,在除了保证自身的质量外,还有很多工作需要做一些前期准备,新手第一次上场难免紧张,所以对于新人把控也要掌握好,那么感兴趣的朋友们来看新人怎么做快手直播吧。 在视频结尾设置悬念  在发布的短视频中,就在结尾给大家制造了一...

短视频新人怎么上热门技巧,短视频想要做好的三个秘诀是什么

短视频新人怎么上热门技巧?如今发展势头最火的,莫过于短视频。很多新人也想尝试短视频领域,但不知道怎样才能做好。今天就给大家介绍一下,短视频想要做好的三个秘诀吧,跟着小编一起来看看吧。 01 剪辑篇 首先就是短视频的素材怎么找呢?现在要找到高质量、无版权并且下载后无需转码的内容,还是可以...

抖音新增加什么功能,有什么作用

最近在刷抖音的时候,我发现抖音新增了好几个功能,抖音增加什么功能?有什么作用?接下来就跟小编一起来看看吧。不知道是分享机制做出来改变还是说现在已经可以分享到朋友圈,有什么惊奇之处。心动的朋友不要错过。 此前将抖音短视频分享到微信和qq后,被分享者只能收到被分享的短视频链接。但现在,点击...

世界10大博物馆(非看不可的十大博物馆)

博物馆是一处非盈利性质,起到征集、典藏、陈列、研究自然和人类文化遗产的文化教育机构,目前中国以5788家博物馆位居全球第五位,而这种聚集人类财富与文化的永久性机构,在全球各个国家中均有建设,那世界范围中有哪些博物馆面积较大呢,世界上那个博物馆规模最大,本文就为大家盘点并简单介绍全球10座...