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

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

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

但是,它不会永远停留在RAM中,请注意。 如果其他内容需要内存,则删除缓存。 此时,需要磁盘访问(此时它再次缓存在RAM中。)

这就是重启后首次访问总是很慢的原因; 数据尚未缓存,因为它从未从文件中读取过。

你必须做出假设并将它们面对现实。 你可以合理地做的第一个是它确实闻起来很像缓存问题!

问自己这些问题:

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

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

    2. ‘物理介质’可能是HDD缓存本身,所以要小心……在linux下你可以使用命令hdparm -W 0 禁用这个“回写”缓存,例如,如果你正在使用驱动器sdahdparm -W 0 /dev/sda将完成这项工作。 您可能希望在完成测试后重新启用它:)

    3. 另一个假设是CPU缓存,看看如何在x86 Windows中执行CPU缓存刷新? 以及如何清除CPU L1和L2缓存

好吧,它可能是也可能不是其中之一,但它不会伤害尝试:)

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

首先检查一下关于慢拳时间执行的MATLAB文章

对于在C#或Java等虚拟机上运行的其他编程语言,这种情况非常普遍。 http://en.wikipedia.org/wiki/Just-in-time_compilation#Startup_delay_and_optimizations

缓存是在C中发生这种情况的一个很好的理由,但仍然是10倍的持续时间很长。重启后系统可能还在加载其他资源。

重启后10分钟后应该运行程序以获得更好的结果。 到那时,所有启动应用程序都将被加载。 (10分钟—-取决于启动应用程序的数量和启动它们所需的时间)

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

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

从这里你可以使用一些低级别的跟踪工具来查看花费的时间。 在linux上一个基本的工具是strace -r 。 其他系统可能有一些类似的工具。 您的编译器还必须附带一个分析器(即GCC或Ggrof)。

这是因为编译器的优化,它的作用是缓存Temoparal Locality的结果并保存激活记录,也节省了时间,因为在链接阶段必须重新加载绑定对象

测量时间有两个组成部分

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

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

这些是分开测量的吗?

你能看看吗? 使Linux缓冲区高速缓存无效

如果重复实验并清除缓存会产生相同的结果,那么您可以推断出文件缓冲区缓存效果没有被考虑在内,而不是重新启动。