Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么C程序第一次运行时速度慢了10倍_C - Fatal编程技术网

为什么C程序第一次运行时速度慢了10倍

为什么C程序第一次运行时速度慢了10倍,c,C,我的C程序使用排序,第一次运行速度比其他时间慢10倍。它使用整数文件进行排序,即使我更改了数字,程序仍然运行得更快。当我重新启动电脑时,第一次运行的程序运行速度慢了10倍。我使用时间来计算时间。即使不再需要数据,操作系统也会将数据保存在RAM中(这称为“缓存”),因此当程序再次运行时,它会从RAM中获取所有数据,而没有磁盘I/O。即使更改数据,这种更改也会首先发生在RAM中,即使在写入文件后,它也会留在那里 提醒你,它不会永远留在RAM中。如果其他东西需要内存,缓存将被删除。在这一点上,需要进行

我的C程序使用排序,第一次运行速度比其他时间慢10倍。它使用整数文件进行排序,即使我更改了数字,程序仍然运行得更快。当我重新启动电脑时,第一次运行的程序运行速度慢了10倍。我使用时间来计算时间。

即使不再需要数据,操作系统也会将数据保存在RAM中(这称为“缓存”),因此当程序再次运行时,它会从RAM中获取所有数据,而没有磁盘I/O。即使更改数据,这种更改也会首先发生在RAM中,即使在写入文件后,它也会留在那里

提醒你,它不会永远留在RAM中。如果其他东西需要内存,缓存将被删除。在这一点上,需要进行磁盘访问(在这一点上,它会再次缓存在RAM中)


这就是为什么重启后第一次访问总是很慢;数据还没有被缓存,因为它从未从文件中读取。

你必须做出假设并面对现实。首先,您可以合理地说,它闻起来确实很像缓存问题

问问自己这些问题:

  • 我的数据是否适合空闲RAM(=我的文件是否由OS FS缓存缓存 ?)
  • 我的数据是否适合CPU数据缓存
  • 我的数据是否适合HDD内部缓存

  • 最容易放弃的假设是FS缓存。在linux下,只需发出
    sync;echo 3>/proc/sys/vm/drop\u在每次调用程序之间缓存
    。第一个将确保缓存的数据将进入物理介质(硬盘),第二个将从内存中删除文件系统缓存的内容

  • “物理介质”可能是硬盘缓存本身,所以要小心。。。在linux下,您可以使用命令
    hdparm-W 0
    禁用此“写回”缓存,例如,如果您正在使用驱动器
    sda
    hdparm-W 0/dev/sda
    将执行此任务。您可能希望在完成测试后重新启用它:)

  • 另一个假设是CPU缓存,看看


嗯,它可能是,也可能不是其中之一,但这并不妨碍尝试:)

这并不是什么新鲜事,不仅仅是你的程序。许多流行的商业软件都面临着这个问题

首先检查一下这个

对于运行在虚拟机(如C#或Java)上的其他编程语言,这是非常常见的。

缓存是在C中发生这种情况的一个很好的原因,但10倍的时间仍然是相当长的。也可能是系统在重新启动后加载了其他资源

你应该在重启10分钟后运行程序,以获得更好的结果。届时,所有启动应用程序都将加载。(10分钟——取决于启动应用程序的数量和启动每个应用程序所需的时间)

如果您的程序不访问网络,则这可能是初始延迟的原因。许多网络协议需要时间来设置。一些例子:

  • DNS:如果您的程序进行任何网络访问,那么很可能需要将主机名解析为IP地址。第一次,它至少需要一次网络往返来填充本地缓存。以下请求将更短
  • 网络文件系统(NFS、CIFS和其他):可以通过网络打开文件
  • 甚至一些看似无害的库函数也可能需要网络访问:主机的用户列表可以位于远程目录服务器上

因此,您可以使用一些低级跟踪工具来查看时间花在哪里。在linux上,一个基本工具是
strace-r
。其他系统可能也有类似的工具。您的编译器还必须附带探查器(即GCC或Valgrind的gprof或Valgrind)。

这是因为编译器进行了优化,它所做的是缓存
Temoparal Locality的结果,并保存激活记录,由于在链接阶段不必重新加载绑定对象,因此也节省了时间。测量的时间有两个组成部分

如果您正在从磁盘读取文件,并将其加载到内存中-并进行排序:

1) 读取文件并将其存储在数组中的时间 2) 分拣时间

这些是分开测量的吗

你能看看这个吗?


如果重复清除缓存的实验得到相同的结果,则可以推断没有考虑文件缓冲区缓存效果,而不是重新启动

我遇到了一个非常类似的问题,但我没有加载一个大文件,所以在第一次执行时我很困惑(缓存不可能是问题)

这为我指明了正确的方向——这是我的实时防病毒保护。每次我重新编译程序时,它都会重新扫描它,认为它可能是恶意的。我将我的项目路径作为“例外”添加到Avira(在我的例子中)的实时病毒防护中


第一次执行时的程序执行现在非常快

这是linux上的吗?如果是这样,它可能将程序信息存储在非活动内存中,从而使下一次启动更加高效。也就是说,如果内存没有被动态分配,请确保创建2个文件,然后使用其中一个文件运行程序。有没有可能看到一些代码?您是否正在运行
time
?如果是这样的话,哪个组件的运行时间是原来的10倍?或者,您使用的是
time\u t time(time\u t*)api?如果是这样,您是否尝试过使用gprof或您最喜欢的XCode/Windows profiler进行评测,以查看哪些函数需要更长的时间?@RutgersMike我使用时间,但输入文件是随机生成的,数据数量相同,但时间仍然相似,为什么会这样?另外,当我在文件中使用不同数量的数据生成时,我第一次运行它的时间比其他时间长。@嘿,当你改变大小时