wordpress笔记主题,网站优化技巧,零代码建站平台,宁波网站建设xpckj自动驾驶的关键路径如下#xff0c;传感器的数据发送给感知模块#xff1b;感知模块根据传感器数据来确定车辆所处的环境#xff0c;比如前方有没有障碍物#xff0c;是不是和车道线保持着适当的距离等#xff1b;感知处理之后的数据传递给规控模块#xff0c;规控根据车…自动驾驶的关键路径如下传感器的数据发送给感知模块感知模块根据传感器数据来确定车辆所处的环境比如前方有没有障碍物是不是和车道线保持着适当的距离等感知处理之后的数据传递给规控模块规控根据车辆当前所处的环境来规划车辆的路线和加减速等最后规控的结果要发送到底盘/动力来做真正的执行。 在自动驾驶的关键路径中对确定性要求是非常高的因为车辆是一个安全产品一旦某个环节消耗的时间不符合确定性的要求那么会造成比较大的影响。比如车辆前方有行人那么车辆就需要及时刹停不可延误。
确定性考虑的是最恶劣的情况假如规控模块要求每次处理规控任务的处理时间不能超过2ms那么就是要求无论系统运行在什么环境下当前系统的负载是怎么样的规控任务的处理时间都不能超过2ms。也就是说如果车辆连续运行了一周假如规控运行的次数是1000万次那么也不允许有一次超过2ms的。
1获取线程实际消耗的cpu时间
如下代码如果要获取planning函数执行消耗的时间。在相当长的一段时间都是直接获取CLOCK_BOOTTIME这种clock id的时间这种时间都是墙上时间。在很多时候用这种时间来表示任务消耗的也是没有问题的但是如果进程中发生了睡眠发生了阻塞使用这种时间就不准确了这种时间不能表示任务实际消耗的cpu时间。
通过函数pthread_getcpuclockid获取的clock表示cpu时间也就是线程实际占用的cpu的时间。
#include stdlib.h
#include stdio.h
#include string.h
#include unistd.h
#include time.h
#include pthread.hvoid planning() {int counter 0;for(int i 0; i 10000; i) {counter;}for (int i 0; i 5; i) {sleep(1);}
}int main() {clockid_t clock_id;struct timespec start_time1;struct timespec end_time1;struct timespec start_time2;struct timespec end_time2;pthread_getcpuclockid(pthread_self(), clock_id);clock_gettime(clock_id, start_time1);clock_gettime(CLOCK_BOOTTIME, start_time2);planning();clock_gettime(clock_id, end_time1);clock_gettime(CLOCK_BOOTTIME, end_time2);printf(real time:%ldns\n, (end_time1.tv_sec * 1000 * 1000 * 1000 end_time1.tv_nsec) - (start_time1.tv_sec * 1000 * 1000 * 1000 start_time1.tv_nsec));printf(wall time:%ldns\n, (end_time2.tv_sec * 1000 * 1000 * 1000 end_time2.tv_nsec) - (start_time2.tv_sec * 1000 * 1000 * 1000 start_time2.tv_nsec));return 0;
}运行结果如下cpu clock id显示的时间是线程实际消耗的时间是514微秒左右wall time是5秒。 2获取线程调度次数
在linux中进程的status文件中显示了线程调度的次数。最后两行表示线程调度次数voluntary_ctxt_switches表示线程主动调度的次数比如当线程睡眠IO阻塞时会触发线程调度这时的调度就是自愿调度nonvoluntary_ctxt_switches表示线程非自愿调度的次数比如当线程的时间片用完被调度器强制调度这种情况就是非自愿调度。
可以通过该文件获取调度次数可以在调用planning之前获取线程的调度次数返回之后再次获取调度次数两者的调度次数差就基本上能表示在planning执行过程中发生的调度次数。这里之所以说是基本上而不是绝对因为在获取调度次数到planning真正被执行以及planning返回到获取调度次数之间也有可能发生调度。 rootwangyanlong-virtual-machine:/home/wangyanlong/test# cat /proc/12744/status Name: a.out Umask: 0022 State: S (sleeping) Tgid: 12744 Ngid: 0 Pid: 12744 PPid: 2374 TracerPid: 0 Uid: 0 0 0 0 Gid: 0 0 0 0 FDSize: 256 Groups: 0 999 NStgid: 12744 NSpid: 12744 NSpgid: 12744 NSsid: 2294 VmPeak: 2712 kB VmSize: 2644 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 1024 kB VmRSS: 1024 kB RssAnon: 0 kB RssFile: 1024 kB RssShmem: 0 kB VmData: 92 kB VmStk: 132 kB VmExe: 4 kB VmLib: 1796 kB VmPTE: 36 kB VmSwap: 0 kB HugetlbPages: 0 kB CoreDumping: 0 THP_enabled: 1 Threads: 1 SigQ: 0/15188 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000000000000 SigCgt: 0000000000000000 CapInh: 0000000000000000 CapPrm: 000001ffffffffff CapEff: 000001ffffffffff CapBnd: 000001ffffffffff CapAmb: 0000000000000000 NoNewPrivs: 0 Seccomp: 0 Seccomp_filters: 0 Speculation_Store_Bypass: thread vulnerable SpeculationIndirectBranch: conditional enabled Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff Cpus_allowed_list: 0-127 Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001 Mems_allowed_list: 0 voluntary_ctxt_switches: 42 nonvoluntary_ctxt_switches: 0 rootwangyanlong-virtual-machine:/home/wangyanlong/test# 有时候当我们统计出来wall time比较大的时候就说这个任务消耗的时间多这样的说服力是比较弱的。这个时候我们就需要获取线程实际消耗的时间结合调度次数来进行分析。
1如果real time和wall time都比较大那么说明就是任务执行实际消耗的时间长需要对任务本身的逻辑进行优化。
2如果real time比较小wall time比较大那么可能有两种情况
①在任务执行期间发生了调度这个时候就需要通过绑核或者提高线程的优先级等方式来保证在任务执行期间不会发生调度。
②任务中存在阻塞的操作等待一个条件满足比如等待一个IO条件等待一个mutex等要结合代码进一步分析。