RIOT 同优先级线程切换基准测试:thread_yield_pingpong 的原理、实现与运行

发布时间:2026/11/7 15:41:28

RIOT 同优先级线程切换基准测试:thread_yield_pingpong 的原理、实现与运行 RIOT 同优先级线程切换基准测试thread_yield_pingpong 的原理、实现与运行【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT导读本文围绕 RIOT 操作系统测试套件中的 thread_yield_pingpong 基准测试应用展开剖析其如何通过两个同优先级线程互相让出 CPUpingpong 式thread_yield()互抛来量化一次上下文切换的开销。读完本文你将理解该基准的计数口径为什么结果是一半的上下文切换次数、result与ticks两个输出指标的含义、底层调度器实现原理以及如何在一台真实板卡上编译、烧录、运行并验证结果。基准测试的设计思路同优先级双线程互抛在实时操作系统中上下文切换context switch开销是衡量内核调度效率的核心指标之一。RIOT 的thread_yield_pingpong采用了一种简洁而巧妙的测量方法其核心思想记录在 README.md 中This test measures the amount of context switches between two threads of the same priority. The result amounts to the number of thread_yield() calls inonethread (half the number of actual context switches).即测量两个同优先级线程之间的上下文切换数量其结果等于一个线程中thread_yield()的调用次数也就是实际上下文切换次数的一半。这一设计的关键在于同优先级两个线程优先级相同因此谁都不比谁高thread_yield()不会触发让位给更高优先级线程的抢占路径而是通过调度器把当前线程移到同优先级运行队列的队尾让出 CPU每次thread_yield()调用都会导致一次真实的线程切换两个线程轮流让位因此每个线程各自经历一半的切换主线程记录的调用次数恰好等于总切换次数的一半。README 还特别说明该测试应用有意与其他类似的 benchmark 应用重复部分代码以便在不同基准之间对比代码体积code size。这一点在 tests/bench 目录下可以得到印证——这里集中存放了 msg_pingpong、mutex_pingpong、thread_flags_pingpong 等结构高度相似的pingpong系列基准它们共享相同的计时、计数与输出骨架区别只在于驱动线程切换的同步原语thread_yield、互斥锁、消息队列、线程标志等。源码逐段解读main.c 的完整测量流程基准的完整实现位于 main.c全文仅约 80 行包含四个核心部分。1. 依赖与默认测量时长#include macros/units.h #include clk.h #include thread.h #include xtimer.h #ifndef TEST_DURATION #define TEST_DURATION (1000000U) #endif依赖 RIOT 的线程抽象thread.h、xtimer 定时器xtimer.h、时钟频率查询clk.h以及单位换算宏macros/units.hTEST_DURATION默认取1000000U单位为微秒即默认测量窗口为 1 秒。该宏允许通过编译期-DTEST_DURATION...覆盖用于延长或缩短采样窗口。2. 全局状态与第二线程volatile unsigned _flag 0; static char _stack[THREAD_STACKSIZE_MAIN]; static void *_second_thread(void *arg) { (void)arg; while (1) { thread_yield(); } return NULL; }_flag是测量窗口的结束标志由定时器回调置位被主线程循环轮询第二线程的栈直接复用THREAD_STACKSIZE_MAIN大小静态分配避免动态内存分配带来的不确定性第二线程进入死循环后只做一件事无限调用thread_yield()。主线程同样如此——两者在 1 秒内像打乒乓球一样互相让出 CPU这正是pingpong名字的由来。3. 主线程创建对线程、设定窗口、循环计数int main(void) { printf(main starting\n); thread_create(_stack, sizeof(_stack), THREAD_PRIORITY_MAIN, 0, _second_thread, NULL, second_thread); xtimer_t timer; timer.callback _timer_callback; uint32_t n 0; xtimer_set(timer, TEST_DURATION); while (!_flag) { thread_yield(); n; } ... }值得注意的两个细节第二线程的优先级显式使用THREAD_PRIORITY_MAIN与主线程完全一致——这是整个基准成立的前提。若第二线程优先级不同thread_yield()的调度行为就会改变例如高优先级线程会让低优先级线程饿死测量结果将失去纯上下文切换开销的意义thread_create的 flags 参数为 0即创建后不立即主动让出 CPU对比 mutex_pingpong 中使用的THREAD_CREATE_WOUT_YIELD。RIOT 默认在线程创建完成后调用thread_yield_higher()因此主线程会先运行并启动定时器随后在首次thread_yield()时切换到第二线程测量随之开始主线程在xtimer_set(timer, TEST_DURATION)之后进入循环每调用一次thread_yield()就对计数器n加一。1 秒后_timer_callback将_flag置 1循环退出测量结束。4. 结果输出result 与 ticksprintf({ \result\ : %PRIu32, n); printf(, \ticks\ : %PRIu32, (uint32_t)((TEST_DURATION/US_PER_MS) * (coreclk()/KHZ(1)))/n); puts( });输出是一行类 JSON 文本包含两个指标字段含义计算方式result测量窗口内主线程的thread_yield()调用次数直接计数nticks平均每次thread_yield()调用消耗的 CPU 周期数tick(TEST_DURATION/US_PER_MS) * (coreclk()/KHZ(1)) / n对ticks公式做单位拆解TEST_DURATION/US_PER_MS将微秒换算为毫秒默认 1 秒 → 1000 mscoreclk()/KHZ(1)将coreclk()返回的 CPU 主频Hz换算为 kHz 数值二者相乘得到测量窗口内理论上的总 tick 数再除以n即为每次thread_yield()调用平均消耗的 CPU 周期数。因此若想估算单次完整上下文切换的开销应将ticks乘以 2因为一次实际切换对应两次线程让位每次让位只算半个切换这与 README 中result 是实际切换次数的一半的说明自洽。测试运行与自动化验证构建与运行该基准是一个标准 RIOT 测试应用其 Makefile 极其精简include ../Makefile.bench_common USEMODULE xtimer include $(RIOTBASE)/Makefile.include其中 Makefile.bench_common 负责定位RIOTBASE并引入公共测试构建规则USEMODULE xtimer显式启用定时器模块msg_pingpong、mutex_pingpong等兄弟基准同样依赖它。在任意受支持板卡上例如使用 native 或某块 Cortex-M 板cd tests/bench/thread_yield_pingpong make BOARDnative -j make BOARDnative term程序启动后首先打印main starting约 1 秒后输出测量结果例如main starting { result : 1234567, ticks : 48 }具体数值取决于 CPU 主频与调度器实现。自动化回归tests/01-run.py与 RIOT 其余测试一致该基准配有 tests/01-run.py基于testrunner框架做自动回归def testfunc(child): child.expect(r{ \result\ : \d(, \ticks\ : \d)? })它只校验输出格式是否符合{ result : 数字(, ticks : 数字)? }的正则——注意ticks部分是可选的说明该字段在部分平台上可能被省略或打印为空自动化测试对两种输出形态都兼容。运行方式make BOARD... flash test板卡适用性限制Makefile.ci 声明了内存不足以运行本基准的板卡BOARD_INSUFFICIENT_MEMORY : \ atmega8 \ nucleo-l011k4 \ stm32f030f4-demo \ #这是因为本测试同时需要静态线程栈THREAD_STACKSIZE_MAIN、xtimer 模块以及 printf 输出对 RAM/Flash 较小的 AVR 或入门级 STM32 板卡而言空间紧张。CI 会据此跳过这些板卡。底层原理thread_yield() 在调度器中的实现要真正理解这个基准测的是什么需要下沉到内核。thread_yield()的实现位于 core/thread.cvoid thread_yield(void) { unsigned old_state irq_disable(); thread_t *me thread_get_active(); if (me-status STATUS_ON_RUNQUEUE) { sched_runq_advance(me-priority); } irq_restore(old_state); thread_yield_higher(); }其执行路径分三步关闭中断irq_disable()保证取出当前线程并操作运行队列这一临界区不被中断或抢占打断推进运行队列sched_runq_advance(me-priority)把当前线程从其优先级的就绪队列头部移到尾部即让出当前执行位置。me-status STATUS_ON_RUNQUEUE的检查确保线程确实在就绪队列上才做移动恢复中断并让位thread_yield_higher()触发实际调度选择运行队列头部的新线程执行完成一次上下文切换。从源码结构可以推断在本基准的两个同优先级线程场景下每次thread_yield()都会经历上述完整三步——关闭/恢复中断、就绪队列指针前移、真正切换到对方线程。因此ticks指标本质上反映的是在目标 CPU 上关中断 就绪队列操作 线程切换 开中断这一整条调度路径的开销而不只是寄存器保存/恢复的裸切换成本。与同族基准的横向对比切换原语决定测量对象thread_yield_pingpong属于 tests/bench 下的pingpong 族基准。对比同目录下的兄弟应用可以更清楚地看出它在基准体系中的定位基准驱动切换的同步原语测量对象thread_yield_pingpongthread_yield()纯协作式让位路径的切换开销msg_pingpongmsg_send()/msg_receive()消息传递机制下的切换开销mutex_pingpongmutex_lock()/mutex_unlock()互斥锁争用下的切换开销thread_flags_pingpong线程标志thread flags标志唤醒机制下的切换开销从代码上看四个应用共享几乎相同的骨架_flag结束标志 xtimer 定时窗口 uint32_t n计数 相同的result/ticks输出格式。以 mutex_pingpong 为例其区别仅在于第二线程循环mutex_lock(_mutex)主线程循环mutex_unlock(_mutex)并计数且线程创建时使用THREAD_CREATE_WOUT_YIELD以避免提前切换。这种有意重复代码正是 README 强调的设计取舍——保证各基准除被测原语外其余条件完全一致从而使代码体积与耗时指标的横向对比具有说服力。使用建议与注意事项优先用 native 或主流 Cortex-M 板卡快速验证BOARDnative无需硬件即可观察输出格式与逻辑需要真实时序数据时选择不在BOARD_INSUFFICIENT_MEMORY列表中的板卡例如nucleo-f401re、samr21-xpro或nrf52840dk调整测量窗口默认 1 秒在慢速 MCU 上可能产生较小计数、放大抖动可通过make CFLAGS-DTEST_DURATION5000000之类的方式延长窗口以平滑结果解读指标时注意口径result是单线程视角的让位次数实际上下文切换数为它的 2 倍ticks是每次让位平均消耗的 CPU 周期单次完整切换成本约为其 2 倍对比代码体积可借助make info-buildsize或size工具分别统计本基准与 mutex_pingpong、msg_pingpong 的镜像大小验证 README 所述重复代码以便对比 code size的设计意图——这也是本基准区别于一般功能测试、被归类到tests/bench的原因。小结thread_yield_pingpong是 RIOT 内核调度性能测量体系中最小巧、最直接的一个基准用两个同优先级线程互抛thread_yield()在固定时间窗口内统计让位次数并换算成每次让位平均消耗的 CPU 周期数。它验证了 RIOT 调度器在同优先级轮转 协作式让位这一核心路径上的真实开销其结果等于一半上下文切换次数的口径、result/ticks输出格式、xtimer 计时骨架以及有意的代码重复策略共同构成了 RIOT 基准测试家族的标准范式可直接作为评估新硬件平台或内核改动对调度性能影响的参考工具。【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/4 17:20:13

Python实现小波变换图像融合:从DWT分解到融合规则

简介:这份文档以基于小波变换的图像融合为研究对象,系统覆盖数字图像处理中多源信息融合的关键技术,适合图像处理、计算机视觉方向的初学者及研究人员用于课题入门或方法回顾。内容从图像融合的起源与像素级、特征级、决策级分类讲起&#xf…

2026/11/7 11:09:31

链游投资联盟与NFT资产化技术解析

我无法根据您提供的输入内容生成符合要求的博文。原因在于:输入中项目标题虽含“Galaxy、Republic、Alameda成立N投资联盟并公布三项链游投资|链游周报04期”,但项目正文为空,关键词未提供具体词汇(仅显示“最新网络热…

2026/11/7 15:39:52

曹县电工证在哪里考保姆级教程:电工证没到手,工作机会就没了

曹县电工证在哪里考保姆级教程:电工证没到手,工作机会就没了 你缺一张电工证,别人就多一份机会。在曹县,找电工相关的工作,电工证几乎是 硬性门槛 ,没有它,连面试资格都没有。尤其是现在企业招聘越来越规范,特种作业证成了“门槛证”,没有它,…

2026/11/7 15:39:52

曹县电工证在哪里考值不值得考

曹县电工证在哪里考值不值得考 之前考的证在外省能不能转过来?这是很多电工朋友心头的疑问。特别是在曹县,有些人在外地打工多年,考了电工证,回来之后却发现手续繁琐,甚至不知从何下手。 值不值得考…

2026/11/7 15:39:52

周先华高压电工证怎么报名 实操考试心里没底怕挂科?这3步教你搞定

周先华高压电工证怎么报名 实操考试心里没底怕挂科?这3步教你搞定 实操考试心里没底怕挂科?你不是一个人。特别是像我们平顶山市从事市政公用工程的朋友,高压电工证不仅是从业门槛,更是日常操作的“安全锁”。很多人在报名时对流程不清楚,对考试内容不…

2026/11/7 15:39:52

建筑特种工和技术工报名怕被坑?真实经历告诉你怎么避坑

建筑特种工和技术工报名怕被坑?真实经历告诉你怎么避坑 不知道去哪报名怕被中介坑,是很多初次报考建筑特种工和技术工的新人最真实的困扰。我自己当初也是在朋友介绍下,稀里糊涂地交了钱,结果证书还没拿到,钱就打水漂了。今天我就从一个过来人的角度,把…

2026/11/7 15:39:52

电工证能在异地年检吗 30天拿证攻略全解析

电工证能在异地年检吗 30天拿证攻略全解析 急需特种作业证才能上岗找工作,电工证作为高需求证书之一,不仅关系到能否入职,还直接决定了薪资水平和发展空间。不少朋友问: 电工证能在异地年检吗 ?更有人担心 多久拿证…

2026/11/7 15:34:51

证书过期了不知道怎么复审延期?硬件施工电工证上岗必备全流程详解

证书过期了不知道怎么复审延期?硬件施工电工证上岗必备全流程详解 证书过期了不知道怎么复审延期?你不是一个人,很多郑州市政公用工程从业者都遇到过这个问题。别急,下面一步步告诉你怎么搞定硬件施工电工证的复审和延期,确保你随时“上岗必备”,不掉链…

2026/11/7 14:54:47

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/7 0:03:08

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科

郑州报考避坑指南:电工证和钳工证怎么选?实操考试心里没底怕挂科 实操考试心里没底怕挂科?你不是一个人。特别是在郑州这样的城市,很多施工企业负责人和一线作业人员在报考电工证和钳工证时都面临着同样的困惑。到底该考哪个证?哪个更适合自己?哪个证书…

2026/11/7 0:03:08

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱?

广西电工证办理流程全解析:外省证怎么转?在哪考最靠谱? 之前考的证在外省能不能转过来?这个问题我遇到太多了,今天就拿广西电工证办理流程来具体说说,别再走弯路了。广西电工证的报考、复审、继续教育这些环节,如果你不了解,真的会吃大亏,尤其对于从…

2026/11/7 0:03:08

电气电工证都有哪些保姆级教程

电气电工证都有哪些保姆级教程 你是不是正愁不知道去哪报名,怕被中介坑?别急,这篇保姆级教程专为河南初次报考人员准备,帮你搞清楚 电气电工证都有哪些 ,以及如何避开那些坑。 电气电工证都有哪些?别被五花八门的证书搞懵了…

2026/11/7 14:54:47

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/7 14:50:12

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑