如何正确实现三重缓冲?

How to correctly implement triple buffering?

我正在尝试模拟视频卡(生产者线程)和监视器(消费者线程),以弄清楚在教育目的上发生了什么。所以这是技术任务 描述:

生产者线程以 1000 fps 的速度产生帧像素数据。消费者线程以 60 fps 的速度运行,并且每一帧它必须至少有 1/60 秒的时间访问最后生成的帧。为简单起见,每一帧都由一些 int* 表示。

所以我的解决方案是我有 2 个指针的数组:一个用于生产者,一个用于消费者。再加上一些免费的、未使用的指针,在任何给定的时间都不为消费者或生产者所有。

#define Producer 0
#define Consumer 1
int* usedPointers[2];
std::atomic<int*> freePointer;

如有错误请指正

我想念memorySemanticsXXXThere are descriptions 但我无法弄清楚我应该在每个线程中使用哪个以及为什么。所以我想就此寻求一些提示。

memorySemanticsXXX 您提到的是围绕 exchange() 行的其余代码。 std::atomic::exchange() 的默认行为是使用 memory_order_seq_cst(您未使用 exchange() 的第二个参数)。

这同时意味着三件事:

  • 您在 exchange() 调用之前编写的任何代码都保证在该调用之前执行(否则编译器优化可以重新排序您的代码) 该执行的结果将在进行 exchange() 调用之前在所有其他线程中可见(CPU 缓存传播)。
  • 与前面相同,但您在 exchange() 行之后编写的代码。

  • exchange() 调用前后的所有代码都按照您编写的确切顺序执行(包括其他原子操作)。

所以,重点是您可以选择不设置这些限制中的一个、两个或所有三个,这 可以 为您带来速度提升。你不应该为这个 烦恼,除非你有性能瓶颈 。如果没有瓶颈,那么只需使用不带第二个参数的 std::atomic(它将采用默认值)。

如果您没有使用所有三个限制,则在编写代码时必须非常小心,否则它可能会意外崩溃。

在此处阅读更多相关信息:Memory order