- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试“粗略地”计算 Linux 系统中线程上下文切换的时间。我写了一个程序,使用管道和多线程来实现这一点。运行程序时,计算的时间显然是错误的(见下面的输出)。我不确定这是因为我为此过程使用了错误的 clock_id 还是我的实现
我已经实现了 sched_setaffinity() 以便只让程序在核心 0 上运行。我试图在代码中留下尽可能多的绒毛以便只测量上下文切换的时间,所以胎面过程只写管道的单个字符和父级读取 0 字节。
我有一个父线程创建一个子线程,子线程之间有一个单向管道来传递数据,子线程运行一个简单的函数来写入管道。
void* thread_1_function()
{
write(fd2[1],"",sizeof("");
}
当父线程创建子线程时,启动时间计数器,然后在子线程写入的管道上调用读取。
int main(int argc, char argv[])
{
//time struct declaration
struct timespec start,end;
//sets program to only use core 0
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
CPU_SET(0,&cpu_set);
if((sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) < 1))
{
int nproc = sysconf(_SC_NPROCESSORS_ONLN);
int k;
printf("Processor used: ");
for(k = 0; k < nproc; ++k)
{
printf("%d ", CPU_ISSET(k, &cpu_set));
}
printf("\n");
if(pipe(fd1) == -1)
{
printf("fd1 pipe error");
return 1;
}
//fail on file descriptor 2 fail
if(pipe(fd2) == -1)
{
printf("fd2 pipe error");
return 1;
}
pthread_t thread_1;
pthread_create(&thread_1, NULL, &thread_1_function, NULL);
pthread_join(thread_1,NULL);
int i;
uint64_t sum = 0;
for(i = 0; i < iterations; ++i)
{
//initalize clock start
clock_gettime(CLOCK_MONOTONIC, &start);
//wait for child thread to write to pipe
read(fd2[0],input,0);
//record clock end
clock_gettime(CLOCK_MONOTONIC, &end);
write(fd1[1],"",sizeof(""));
uint64_t diff;
diff = billion * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
diff = diff;
sum += diff;
}
我在运行时得到的结果通常是这样的:
3000
3000
4000
2000
12000
3000
5000
等等,当我检查返回到开始和结束 timespec 结构的时间时,我看到 tv_nsec 似乎也是一个“四舍五入”的数字:
start.tv_nsec: 714885000, end.tv_nsec: 714888000
这是由于 clock_monotonic 对我尝试测量的内容不够精确,还是我忽略了其他一些问题造成的?
最佳答案
i see that tv_nsec seems to be a 'rounded' number as well:
2626, 714885000, 2626, 714888000
Would this be caused by a clock_monotonic not being precise enough for what im attempting to measure, or some other problem that i'm overlooking?
是的,这是可能的。系统支持的每个时钟都有固定的分辨率。 struct timespec
能够支持具有纳秒分辨率的时钟,但这并不意味着您可以期望每个时钟实际上都具有这样的分辨率。看起来您的 CLOCK_MONOTONIC
可能具有 1 微秒(1000 纳秒)的分辨率,但您可以通过 clock_getres()
函数进行检查。
如果它可用,那么您可以尝试 CLOCK_PROCESS_CPUTIME_ID
。对于您来说,这可能比 CLOCK_MONOTONIC
具有更高的分辨率,但请注意,单微秒的分辨率非常精确——在现代机器上大约是每 3000 个 CPU 周期一个滴答。
即便如此,我发现您的方法存在几个可能的问题:
虽然您将进程设置为对单个 CPU 具有亲和性,但这并不妨碍系统在该 CPU 上也调度其他进程。因此,除非您采取了额外的措施,否则您无法确定(甚至不太可能)从您的一个程序线程切换的每个上下文都到另一个线程。
您启动第二个线程,然后立即加入它。之后你的线程之间不再有上下文切换,因为你的第二个线程在成功加入后不再存在。
read()
可能会或可能不会检查错误,并且它当然不会传输任何数据。我完全不清楚为什么您将调用的时间与上下文切换的时间标识在一起。
如果上下文切换确实发生在您正在计时的空间中,那么至少需要发生两次 - 离开您的程序并返回到它。此外,您还要测量在其他上下文中运行的任何其他内容所消耗的时间,而不仅仅是切换时间。因此,1000 纳秒的步长可能反射(reflect)时间片,而不是切换时间。
您的主线程正在将空字符写入管道的写入端,但似乎没有任何内容在读取它们。如果确实没有那么这最终将填满管道的缓冲区和 block 。我迷失了目标。
关于c - 上下文切换场景下clock_gettime()的准确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54447430/
当我尝试获取 ns 时间时,我在内核为 2.6.18 的 Linux 中遇到了问题,如下所示: #include #include #include int main(void) { s
我在我的 Mac 上用 C 来做基准测试。此处的代码可以编译并运行,但输出中会出现大约 1Hz 的故障。该程序“应该”每 2 毫秒中断一次,并报告上次中断时间的数据。默认设置是打印以下内容到终端 ev
我在 Linux 2.6 上使用 clock_gettime()(来自 time.h)来控制线程循环中的计时。我需要在 +/- 5mS 时间范围内有 500mS。它似乎给了我 500 毫秒,然后开始漂
我有一个在linux上运行的非常简单的代码,如下所示: struct timespec SysTime_Test; #define BILLION 1000000000L SysTime_Test.
我正在运行一个进行长时间计算的 Haskell 程序。经过一些分析和跟踪后,我注意到以下内容: $ /usr/bin/time -v ./hl test.hl 9000045000050000 Com
我正在尝试获取 Ubuntu 上进程消耗的 CPU 时间。据我所知,有两个函数可以完成这项工作:getrusage() 和 clock_gettime(CLOCK_PROCESS_CPUTIME_ID
我试图测量一段代码的时间,并注意到当我从我的编辑器 QtCreator 中运行程序时,与我从 gnome 终端中启动的 bash shell 运行它时相比,时间快了大约 50ns。我使用 Ubuntu
我在多线程代码中使用 timespec 结构 - 一个线程调用 clock_gettime()填充全局 timespec 结构,另一个 - 读取该结构。问题:是clock_gettime()调用原子还
我正在编写一个简单的程序,它检查耗时是否超过 1 秒。我使用clock_gettime()获取开始时间,然后调用sleep(5),获取新时间并检查差异是否大于1;我睡了 5 秒,那么它应该大于 5,但
我正在尝试使用 clock_gettime 函数获取以下代码的运行时间。但是,当我运行代码时,每次运行时我都会收到 0.0000 的时间。我也分别输出了开始和停止时间,我收到了完全相同的答案。 str
当使用下面的示例代码时,我认为 tv_nsec 值是循环的,因为它只是一个long; #include using namespace std; #include int main(int arg
我阅读了以下手册: http://linux.die.net/man/3/clock_gettime 然后我写了下面的代码: #include int main() { struct tim
Linux 中的 clock_gettime 函数在调用以测量给定代码段的运行时间时,内部使用哪个系统硬件计时器将纳秒级分辨率返回给用户代码? 最佳答案 现代 CPU 以几 GHz 时钟频率运行。 1
clock_gettime 不再适用于 MacOS Sierra。很确定在 Xcode 8 出来之前我已经正确地编译了这个。我真的很困惑如何才能让它正确编译。 #include #include
我正在尝试使用 clock_gettime 函数,但无法弄清楚所需的 header 是什么(或者如果这不是 header 的问题,我做错了什么)。这是我的代码: #include #include
我想用 clock_gettime 测量挂钟时间,但每次运行我的代码时,它都显示 0。这是为什么? (我希望我的结果以毫秒为单位。) #include #include #include #in
我正在编写一个简单的程序,用于检查耗时是否超过 1 秒。我使用 clock_gettime() 获取开始时间,然后调用 sleep(5),获取新时间并检查差异是否大于 1;我睡了 5 秒,那么它应该大
我在我的 C++ 程序中使用 clock_gettime() 来获取当前时间。但是,返回值是自 UTC 纪元以来的秒数。在夏令时期间,当时间偏移一小时时,此代码在我的时区可能会搞砸。 系统本身有 NT
我想要以微秒为单位的当前系统时间,所以我使用 clock_gettime 编写了一个程序,但它有时会返回负值。有人可以帮我解决这个问题吗? int main(void) { struct ti
我正在尝试用这个类分析一个程序: namespace smtx{ class CPerformance_clock { timespec t1; tim
我是一名优秀的程序员,十分优秀!