论高性能编程之乱序执行问题

发布于 2020-03-31 22:36:54

解决乱序执行问题是高性能编程必须要迈过去的坎儿,尤其是多线程环境下的无锁编程。乱序执行问题由编译阶段的编译器优化和运行阶段的CPU指令重排引起。

对于编译器优化导致的语句乱序执行问题,这个很好解决:在不希望被编译器优化而发生语句重排的地方,插入编译器特有的语句即可。以gcc为例,加入如下compiler barriers即可:

asm volatile("" ::: "memory");

接下来重点介绍一下大家容易误解的CPU乱序执行问题。我认为网上讲到的CPU乱序执行问题是由CPU指令重排导致的。因此我们有必要了解CPU指令重排的前提和背景,以避免不必要的恐慌。CPU指令重排是针对微观的机器指令,我们的代码是由相对宏观的程序语句构成,二者存在宏观到微观的映射关系,但绝对不是等价关系。我觉得大家对CPU指令重排产生误解的一个地方,是没有区分清楚机器指令和程序语句的关系。

CPU指令重排在主流CPU中是存在的,但CPU会严格按照我们的程序语句(程序逻辑)执行,否则就是CPU或编译器的重大bug了。因此从单个线程的执行来看,尽管可能存在CPU指令重排的情况,但对应于宏观的程序语句而言,哪条语句先执行,哪条语句后执行,并不会违背我们的程序逻辑,必须保证语句执行的先后顺序,否则我们的程序就没法写了。

我最近在做无锁化编程,需要关心多线程环境下的数据可见性或数据访问一致性问题。前段时间在网上查资料,差点被CPU乱序问题搞疯掉。CPU乱序执行问题,我认为其实就是多线程环境下,数据更改后在不同线程的可见性问题或者多线程访问数据的一致性问题。搞清楚这一点,再结合上述CPU指令重排背景知识,就不会被CPU乱序执行这个术语给吓倒了。

总结一下,CPU乱序执行这个说法不够严谨和科学,容易误导大家,多线程环境下对应的说法是数据可见性或者数据访问一致性问题。搞清楚问题真相后,提醒自己和大家不要被网上以讹传讹的资料所蒙蔽。
0 条评论

发布
问题