我有一个程序需要以100%的性能执行,但我发现它有时暂停超过20 uSec。我已经挣扎了一段时间,无法找到原因/解释。
所以我的问题是: 为什么我的节目"暂停" /"停滞不前"每隔20微秒?
为了调查这一点,我写了以下小程序:
#include <string.h>
#include <iostream>
#include <signal.h>
using namespace std;
unsigned long long get_time_in_ns(void)
{
struct timespec tmp;
if (clock_gettime(CLOCK_MONOTONIC, &tmp) == 0)
{
return tmp.tv_sec * 1000000000 + tmp.tv_nsec;
}
else
{
exit(0);
}
}
bool go_on = true;
static void Sig(int sig)
{
(void)sig;
go_on = false;
}
int main()
{
unsigned long long t1=0;
unsigned long long t2=0;
unsigned long long t3=0;
unsigned long long t4=0;
unsigned long long t5=0;
unsigned long long t2saved=0;
unsigned long long t3saved=0;
unsigned long long t4saved=0;
unsigned long long t5saved=0;
struct sigaction sig;
memset(&sig, 0, sizeof(sig));
sig.sa_handler = Sig;
if (sigaction(SIGINT, &sig, 0) < 0)
{
cout << "sigaction failed" << endl;
return 0;
}
while (go_on)
{
t1 = get_time_in_ns();
t2 = get_time_in_ns();
t3 = get_time_in_ns();
t4 = get_time_in_ns();
t5 = get_time_in_ns();
if ((t2-t1)>t2saved) t2saved = t2-t1;
if ((t3-t2)>t3saved) t3saved = t3-t2;
if ((t4-t3)>t4saved) t4saved = t4-t3;
if ((t5-t4)>t5saved) t5saved = t5-t4;
cout <<
t1 << " " <<
t2-t1 << " " <<
t3-t2 << " " <<
t4-t3 << " " <<
t5-t4 << " " <<
t2saved << " " <<
t3saved << " " <<
t4saved << " " <<
t5saved << endl;
}
cout << endl << "Closing..." << endl;
return 0;
}
程序只是测试调用函数需要多长时间&#34; get_time_in_ns&#34;。该程序连续5次执行此操作。该程序还跟踪测量的最长时间。
通常调用该函数需要30 ns,但有时需要200 ns。我不明白。
程序输出的一小部分是:
8909078678739 37 29 28 28 17334 17164 17458 18083
8909078680355 36 30 29 28 17334 17164 17458 18083
8909078681947 38 28 28 27 17334 17164 17458 18083
8909078683521 37 29 28 27 17334 17164 17458 18083
8909078685096 39 27 28 29 17334 17164 17458 18083
8909078686665 37 29 28 28 17334 17164 17458 18083
8909078688256 37 29 28 28 17334 17164 17458 18083
8909078689827 37 27 28 28 17334 17164 17458 18083
输出显示正常通话时间约为。 30ns(第2列至第5列),但最大时间接近20000ns(第6至9列)。
我开始这样的程序:
chrt -f 99 nice -n -20 myprogram
任何想法为什么电话通常需要20ns才需要20000ns?
程序在双Xeon(每个8核)机器上执行。
我使用SSH连接。
顶部显示:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8107 root rt -20 16788 1448 1292 S 3.0 0.0 0:00.88 myprogram
2327 root 20 0 69848 7552 5056 S 1.3 0.0 0:37.07 sshd
答案 0 :(得分:2)
即使最低的niceness值也不是实时优先级 - 它仍然在策略SCHED_OTHER
中,这是一个循环时间分享策略。您需要根据需要使用sched_setscheduler()
切换为实时日程安排策略,SCHED_FIFO
或SCHED_RR
。
请注意,如果它不是唯一运行的任务,那么仍然不会给你绝对的100%CPU。如果您不间断地运行任务,Linux仍会将百分之几的CPU时间授予非实时任务,这样一个失控的RT任务将无法有效地挂起机器。当然,需要100%CPU时间的实时任务不太可能正确执行。
编辑:鉴于该进程已经使用RT调度程序运行(漂亮的值仅与SCHED_OTHER
相关,因此如此指出另外设置那些是没有意义的),我的其余部分仍然适用于如何以及为何仍在运行其他任务(请记住,还有一些内核任务)。
唯一比此更好的方法可能是将一个CPU核心专用于任务以充分利用它。显然这仅适用于多核CPU。这里有一个问题:Whole one core dedicated to single process