如何正确实现三重缓冲? [英] How to correctly implement triple buffering?

查看:214
本文介绍了如何正确实现三重缓冲?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试模拟视频卡(生产者线程)和监视器(消费者线程),以了解在教育方面发生了什么.所以这是技术任务说明:

I am trying to simulate videocard (producer thread) and a monitor(consumer thread), to figure out what is going on in educational purposes. So here is the technical task description:

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

Producer thread produces frames pixel data at 1000 fps. Consumer thread runs at 60 fps and every frame it must have access to last produced frame for at least 1/60th of second. Each frame is represented by some int*, for simplicity.

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

So my solution is that i have array of 2 pointers: one for producer, one for consumer. And plus some free, unused pointer, which is not owned by consumer or producer at any given moment of time.

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

  • producer 总是将帧像素写入usedPointers[Producer],然后usedPointers[Producer] = freePointer.exchange(usedPointers[Producer], memorySemanticsProducer);所以最后一个完整生成的帧现在由 freePointer 指向,并且可以自由写入新帧,而不是破坏最后一个实际完整帧.

    • producer always writes frame pixels to usedPointers[Producer], then does usedPointers[Producer] = freePointer.exchange(usedPointers[Producer], memorySemanticsProducer); so that last completely produced frame is now pointed by freePointer, and its free to write new frame, not destroying last actual complete frame.

      consumer 做了 usedPointers[Consumer] = freePointer.exchange(usedPointers[Consumer], memorySemanticsConsumer); 以便它拥有最后的实际帧数据,然后可以自由访问 usedPointers[Consumer] 只要它愿意.

      consumer does usedPointers[Consumer] = freePointer.exchange(usedPointers[Consumer], memorySemanticsConsumer); so that it would own last actual frame data, and then is free to access usedPointers[Consumer] as long, as it desires to.

      如果我错了,请纠正我.

      Correct me if i am wrong.

      我想念什么是 memorySemanticsXXX.有描述 但我不知道我应该在每个线程中使用哪个为什么.所以我想就此寻求一些提示.

      I miss what is memorySemanticsXXX. There are descriptions but i cannot figure out which exactly should i use in every thread and why. So i am asking for some hints on that.

      推荐答案

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

      memorySemanticsXXX you're mentioning are about the rest of your code surrounding the exchange() lines. The default behavior for std::atomic::exchange() is that memory_order_seq_cst is used (the second parameter for exchange() you're not using).

      这同时意味着三件事:

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

      • Any code you wrote before your exchange() call is guaranteed to execute before that call (otherwise compiler optimizations can reorder your code) and the results of that execution will be visible in all other threads (CPU cache propagation) before the exchange() call is made.
      • The same as previous but for the code you wrote after your exchange() line.

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

      All of the code before and after exchange() call is executed in the exact order you wrote it (including other atomic operations).

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

      So, the whole point is that you may choose not to have one, two or all three of these restrictions, which can bring you speed improvements. You shouldn't bother with this unless you have a performance bottleneck. If there's no bottleneck then just use std::atomic without the second parameter (it will take the default value).

      如果您不使用所有三个限制,则必须非常小心地编写代码,否则可能会意外崩溃.

      In case you don't use all three restrictions you have to be really careful writing your code otherwise it can unpredictably crash.

      在此处阅读更多相关信息:内存顺序

      Read more about it here: Memory order

      这篇关于如何正确实现三重缓冲?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆