我正试图在Ubuntu 8.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和调度?提前谢谢!
答案 0 :(得分:3)
如果你在每次测试迭代之前立即调用nanosleep()来休眠一秒钟,你应该为每次测试得到一个“新鲜”的时间片。如果使用100HZ定时器中断编译内核,并且定时功能在10ms内完成,那么您应该能够避免定时器中断以这种方式命中。
要最大限度地减少其他中断,请取消配置所有网络设备,在不交换的情况下配置系统,并确保它处于静止状态。
答案 1 :(得分:2)
棘手。我不认为你可以关闭操作系统并保证严格的安排。
我会将其颠倒过来:鉴于它运行速度如此之快,请多次运行以收集结果分布。鉴于标准Ubuntu Linux不是狭义上的实时操作系统,所有替代算法都将在相同的设置中运行 - 然后您可以比较您的分布(使用从汇总统计到分位数到qqplots的任何内容)。您可以与Python,R或Octave进行比较,以最适合您的方式进行比较。
答案 2 :(得分:2)
自FreeDOS以来,您可能无法运行it's a single process OS。
以下是第二个链接的相关文字:
Microsoft的DOS实现,即de 事实上的DOS系统标准 x86世界,是单用户, 单任务操作系统。它 提供对硬件的原始访问,以及 只有OS API的最小层 像文件I / O这样的东西。这是一个 嵌入式的好处 系统,因为你经常只需要 没有一个完成任务 以你的方式操作系统。
DOS(原生)没有概念 线程,没有多重概念, 正在进行的流程。应用 软件通过网络进行系统调用 使用中断接口,调用 要处理的各种硬件中断 像视频和音频这样的东西 调用软件中断来处理 阅读等各种各样的事情 目录,执行文件等 类推。
当然,您可能会获得实际将FreeDOS引导到实际硬件上的最佳性能,而不是在模拟器中。
我实际上并没有使用 FreeDOS,但我认为既然你的程序似乎是标准的C,你就可以使用FreeDOS的标准编译器。
答案 3 :(得分:2)
如果您的程序在几毫秒内运行,并且您的程序在Linux上运行, 确保您的计时器频率(在Linux上)设置为100Hz(不是1000Hz)。 (cd / usr / src / linux; make menuconfig,查看“处理器类型和功能” - &gt;“计时器频率”) 这样你的CPU每隔10ms就会被中断。
此外,考虑到Linux上的默认CPU时间片是100毫秒,所以如果你的运行时间为几毫秒,你就不会被取消预定。
此外,您在fn()上循环101次。请考虑将fn()作为无操作来正确校准您的系统。
制作统计数据(平均值+ stddev)而不是打印太多次(这将消耗您的预定时间片,并且终端最终会获得计划等等......避免这样做。)
答案 4 :(得分:1)
您可以使用 chrt -f 99 ./test 以最大实时优先级运行./test。然后至少它不会被其他用户空间进程打断。
此外,安装 linux-rt 软件包将安装一个实时内核,通过线程中断可以更好地控制中断处理程序的优先级。
答案 5 :(得分:0)
如果您以root用户身份运行,则可以调用sched_setscheduler()并为自己提供实时优先级。查看文档。
答案 6 :(得分:0)
也许有一些方法可以禁用Linux上的抢占式调度,但可能不需要它。您可以使用/proc/<pid>/schedstat
中的信息或/proc
中的其他对象来感知您何时被抢占,并忽略这些时间示例。