2

我正在开发计算几何领域的数据结构和算法。能够可靠地比较两种算法的运行时间对我来说非常重要。

问题是,当我运行一个算法并且它运行了 30 分钟时,我不能说这 30 分钟用于执行算法而不是播放 mp3。

我有一台运行 Ubuntu 13.04 的 Intel® Core™ i7-2600 CPU @ 3.40GHz × 8 处理器计算机。我所有的程序都是用 C++ 编写的,并且只使用用 C 或 C++ 编写的库。

  1. 这是否意味着我可以安全地并行运行 6 个实验,而操作系统会将另外 2 个用于自己的业务?

  2. 我应该将实验作为一个程序的 6 个线程运行,还是制作 6 个不同的可执行文件并运行它们?

  3. 这两种方法有什么区别?

4

2 回答 2

3

如果您想要一致的结果,一次运行一个基准测试将提高这种可能性 - 因为不同的任务更有可能:

  1. 从一个 CPU 移动到另一个 CPU(从而使加载到缓存中的任何内容都没有意义)。
  2. 造成内存带宽和缓存压力,导致干扰另一个进程。

如果您在播放 MP3、下载大片长片等的同时运行基准测试,那么您将不知道这是否确实干扰(或干扰了多少)您的 CPU 密集型任务 - 您可以,可能反过来说,如果音乐开始变得断断续续,或者下载超时...... ;) 与并行运行多个任务一样,缓存和从处理器到处理器内核的移动将是最重要的影响。

您可能会发现,如果您在“一切都开启”的情况下运行一组基准测试,而在“一切都关闭”的情况下运行另一组基准测试,那并没有什么区别。但你也可能会发现它确实有所作为。

这同样适用于运行一个或多个基准测试。尝试并行运行 6 个,并比较每个基准测试本身在没有其他运行的情况下运行的时间。

你只有通过比较不同的案例才能知道这一点。

如果没有影响,您可以在进行基准测试时继续播放音乐、下载最新的大片等,因为您知道 0.01% 的差异对应用程序的整体性能并不重要。

根据经验,我发现如果你在后台运行一堆其他“轻”的东西通常不会有太大的不同,但它会增加从一次运行到另一次运行的变化量。同样,如果基准测试运行半小时,则可能无关紧要 - 毕竟,从一次运行到另一次运行,您可能会在运行时有足够的变化,仅仅是从 CPU 和操作系统中不同的一般事物来看,纯粹是由于“事情不会每次都完全相同”的因素,它不会产生足够的差异。

如果您正在做小的优化,例如切换编译器选项,结果差异为 0.5%,但运行之间的差异为 1%,那么您需要运行多次运行以显示实际差异,以及来自其他进程的更多干扰,您无法衡量微小变化的可能性就越大。有时,许多小的变化一起可以产生显着的差异(例如,如果你移动一个函数 F1 以允许它被内联,然后对函数 F2 做同样的事情,它们加起来相当于 1% 的改进,但单独它是不可测量的,因为它隐藏在噪音中)。噪音越大,您就越有可能“错过”一些微小但最终有益的变化。

于 2013-08-11T17:47:49.180 回答
1

首先:Intel i7-2600 有 4 个“真正的”核心,但每个核心可以并行运行两个线程。这种“超线程”比通过操作系统调度程序抢占的传统线程更快。因为可以在另一个线程上继续执行,所以如果一个线程必须等待很短的时间(例如在缓存未命中后从主内存读取值时),超线程往往会稍微增加吞吐量。因此,在一个超线程内核上运行的两个进程的综合性能通常比在同一内核上运行的单个进程的性能高 10% 到 20%。但是,在高速缓存压力较高的情况下,综合性能可能会更差。

但是,更重要的是您的性能时序需求:如果一个内核上的两个线程的综合性能为 120%,则意味着单线程性能下降到 60%!

据我所知,linux内核调度器知道超线程,所以它会尽量让每个核心上的第二个线程保持空闲,如果第一个线程正在做繁重的工作,如果还有可用的核心。因此,如果您只并行启动 3 个计时进程,并为您的桌面留下一个内核,并且不做太多的副业(如编译等),那么您应该得到相当一致的计时数据!如果您启动 4 个进程,请确保桌面确实处于空闲状态。如果您启动 5 个或更多进程,由于超线程,预计会出现不一致的计时结果。

如果您在 shell 上使用时间来为命令计时,则报告的用户和系统时间往往比总时间更准确。这是因为操作系统仅在该时间分别算作用户和系统时间,即该进程实际上分别在用户空间或系统中运行。如果您的代码不做太多 I/O,系统时间应该很短,而用户时间应该接近总运行时间。

于 2013-08-11T18:43:27.193 回答