如何确保多核系统中数据的一致性
2021-03-04 17:00
在多核系统中,不同核上运行的任务多多少少会有共享数据。 对共享数据内存的并发访问可能会导致数据不一致。 一般来说,当多个任务或者中断访问相同数据内存时,必须考虑到这一点,换句话说,当系统使用并行(多核)或并发(单核)执行代码时,任务上下文切换发生并且在任务之间共享数据时,数据一致性就会成为一个问题。
假如有两个任务,分别为Task A和Task B,其中Task A的优先级高于Task B。Task A每次访问均使X加2,Task B每次访问均使X加1。因此这两个任务中都要执行(step1)、修改(step2)、写(step3)三步操作。如果没有原子操作,则可能会发现以下情况,如图1所示:
- Task B执行读取(step1) X=5,并临时存储(堆栈或MCU寄存器中);
- Task A 优先级高于Task B, Task B被打断;
- Task A执行读,修改,写操作,将X=7写回内存中;
- Task B将之前临时存储的X(操作2)取出,并加1,将X=6写回内存。
显然,开发人员期待的 结果是X = 8,但是最终的确实X = 6,Task A的运算失效。在AUTOSAR系统中,RTE必须保证大量通信不被数据一致性问题破坏。如果需要,RTE必须采用合适的手段,那有哪些手段呢?
将访问共同内存内存的运行实体放置在同一个Task中,这样运行实体就只能顺序执行,两者不可能发生干扰,数据一致性就可以得到保证。
如果需要保证一致性的代码很短,中断阻塞是一种合适的方法。这可以通过禁用挂起所有中断、或仅操作系统中断或(如果硬件支持)仅某些中断级别来实现。一般来说,这种机制必须谨慎使用,因为它可能会影响更高优先级的任务的运行。适当合适的使用操作系统的资源,使用IPC来确保数据的一致性,可以使影响的高优先级任务更少。但是缺点是由于更复杂的机制,实现可能会消耗更多的资源(代码、运行时)。这种机制的适当性取决于OSs/内核的数量和/或可用资源的数量。禁止任务的抢占。这可以通过为受影响的任务分配相同的优先级,为受影响的任务分配相同的内部操作系统资源,或者将OS的任务配置为非抢占性来实现。这种机制在多分区系统中可能不合适。当需要保护的一个运行实体处于活动状态时,包含需要被该策略保护的运行实体的任务不允许抢占其他包含需要被该策略保护的运行实体的任务。例如:-R1放置在任务T1中,R2放置在任务T2中,R3a放置在任务T3a中,R3b放置在T3b中,R4放置在T4中。
-任务的优先级T4 > T3a =T3b> T2 > T1 。T4总是可以抢占所有其他任务(比所有其他任务更高的优先级)。T3b可以抢占T2 (T3b的优先级更高,没有合作限制)。T3a不能抢占T2 (T3a的更高优先权,但相同的合作上下文)。因此,可运行R2对普通数据的访问不会干扰可运行R3a对数据的访问。然而,如果任务T3a和T2都准备运行,则可以保证T3a先运行。- T1永远不能抢占其他任务,因为分配的优先级最低。创建数据项的副本,以保证不同任务上下文中的并发访问不会发生冲突,因为某些访问被重定向到副本。例如存在T1和T2两个任务,交互的数据为Data,复制选项为Data*,其中T1优先级高于T2。在激活T2任务前,将Data复制至Data*,T2直接操作Data*,操作完之后,再将Data*赋值给Data,这样来保证数据的一致性。
来源:汽车ECU开发
作者:eng2mot
同类信息