代码之家  ›  专栏  ›  技术社区  ›  Matthew Iselin

如何确保我的程序从头到尾不中断地运行?

  •  2
  • Matthew Iselin  · 技术社区  · 15 年前

    我正在尝试在Ubuntu8.10上使用RDTSC(我尝试过的任何其他分析软件都无法达到我需要的解决方案)对代码计时。但是,我总是从任务切换和中断触发中获取异常值,这导致我的统计数据无效。

    考虑到我的程序在几毫秒内运行,是否可以禁用我的环境中的所有中断(本质上会关闭任务开关)?或者我需要去一个操作系统,它能让我更强大?我最好使用自己的操作系统内核来执行这个计时代码吗?我正试图证明一个算法的最佳/最差情况下的性能,因此它必须在时间上完全可靠。

    我目前使用的相关代码是:

    inline uint64_t rdtsc()
    {
        uint64_t ret;
        asm volatile("rdtsc" : "=A" (ret));
        return ret;
    }
    
    void test(int readable_out, uint32_t start, uint32_t end, uint32_t (*fn)(uint32_t, uint32_t))
    {
        int i;
        for(i = 0; i <= 100; i++)
        {
            uint64_t clock1 = rdtsc();
            uint32_t ans = fn(start, end);
            uint64_t clock2 = rdtsc();
    
            uint64_t diff = clock2 - clock1;
    
            if(readable_out)
                printf("[%3d]\t\t%u [%llu]\n", i, ans, diff);
            else
                printf("%llu\n", diff);
        }
    }
    

    对于那些注意到我在这段代码中没有正确处理溢出条件的人来说,还有额外的要点。在这个阶段,我只是想得到一个一致的输出,而不会因为我的程序丢失了时间片而突然跳转。

    我的程序的好值是-20。

    那么,概括地说,我是否可以在不中断操作系统的情况下运行这段代码?或者我需要在Ring0中的裸硬件上运行它,以便禁用IRQ和调度?事先谢谢!

    7 回复  |  直到 15 年前
        1
  •  3
  •   caf    15 年前

    如果在每次测试迭代之前立即调用nanosleep()睡眠一秒钟左右,那么您应该为每个测试获得一个“新的”时间段。如果您使用100Hz计时器中断编译内核,并且您的定时函数在10毫秒内完成,那么您应该能够避免计时器中断以这种方式对您造成影响。

    要最小化其他中断,请取消对所有网络设备的配置,在不交换的情况下配置系统,并确保系统处于静止状态。

        2
  •  2
  •   Dirk is no longer here    15 年前

    狡猾的我认为你不能关闭操作系统,保证严格的调度。

    我会把这个颠倒过来:考虑到它运行得这么快,运行它很多次来收集结果的分布。考虑到标准的Ubuntu Linux在狭义上不是实时操作系统,所有的替代算法都将在同一个设置中运行——然后您可以比较您的分布(使用从汇总统计数据到分位数到qqplots的任何东西)。你可以用python,或者r,或者octave来做比较。哪一个最适合你。

        3
  •  2
  •   Mark Rushakoff    15 年前

    你也许可以逃避跑步 FreeDOS ,因为 it's a single process OS .

    下面是第二个链接的相关文本:

    微软的DOS实现,即 中DOS系统的事实标准 x86世界,是一个单一用户, 单任务操作系统。它 提供对硬件的原始访问,以及 只有一个最基本的操作系统API层 像文件I/O。这是一个 说到嵌入式系统,这是件好事 系统,因为你经常需要 在没有 以您的方式操作系统。

    DOS(本机)没有 线程,没有多个概念, 正在进行的过程。应用 软件通过 使用中断接口,调用 处理各种硬件中断 像视频和音频,以及 调用软件中断来处理 各种各样的东西,比如阅读 目录,执行文件,等等 第四。

    当然,在实际硬件上而不是在模拟器中启动freedos,您可能会获得最佳性能。

    实际上我没有 习惯于 Freedos,但我假设由于您的程序似乎是标准的C,所以您可以使用Freedos的任何标准编译器。

        4
  •  2
  •   Nicolas Viennot    15 年前

    如果您的程序以毫秒为单位运行,并且在Linux上运行, 确保您的计时器频率(在Linux上)设置为100Hz(而不是1000Hz)。 (cd/usr/src/linux;make menuconfig,并查看“处理器类型和功能”->“计时器频率”)。 这样,CPU每10毫秒就会中断一次。

    此外,考虑到Linux上的默认CPU时间片是100毫秒,因此,如果您的CPU运行时间为几毫秒,那么在很好的-20级别下,您将不会被重新安排。

    另外,在fn()上循环101次。请考虑将fn()设置为no op以正确校准系统。

    进行统计(Average+StdDev),而不是打印太多次(这将消耗您的计划时间段,最终终端将获得计划等)。避免那样做)。

    RDTSC benchmark sample code

        5
  •  1
  •   Karl Voigtland    15 年前

    你可以使用 CHRT-F 99./测试 以最大实时优先级运行/测试。至少不会被其他用户空间进程中断。

    另外,安装 Linux RTT 这个包将安装一个实时内核,它将通过线程中断为您提供对中断处理程序优先级的更多控制。

        6
  •  0
  •   William Pursell    15 年前

    如果以根用户身份运行,则可以调用sched_setscheduler(),并为自己提供实时优先级。检查文档。

        7
  •  0
  •   SingleNegationElimination    15 年前

    也许有某种方法可以禁用Linux上的抢占式调度,但可能不需要。您可能会使用来自 /proc/<pid>/schedstat 或其他物体 /proc 感觉你什么时候被抢先,忽略那些计时样本。