gpt4 book ai didi

c++ - DMA 的同步要求

转载 作者:行者123 更新时间:2023-12-01 14:20:05 27 4
gpt4 key购买 nike

我给你讲个故事:

我有两个缓冲区设置,用于执行所谓的 ping ponging。我有一个指向每个缓冲区的 DMA 系统。

系统设置为 DMA 将数据写入一个缓冲区,而中断处理另一个缓冲区中的数据。

看起来像这样:

#include <atomic>
#include <array>
#include <algorithm>

using buf_t = std::array<std::uint32_t, 32>;

std::array<buf_t,2> ping_pong;

/*
* In this example I am just going to push the data to a "peripheral"
*/
#define PORT (*(volatile std::uint32_t*)0x1234)


void handle_data(buf_t const& data)
{
std::for_each(std::begin(data),std::end(data), [](auto x){
PORT = x;
});
}

void isr1(void)
{
std::atomic_thread_fence(std::memory_order::memory_order_acquire);
handle_data(ping_pong[0]);
}
void isr2(void)
{
std::atomic_thread_fence(std::memory_order::memory_order_acquire);
handle_data(ping_pong[1]);
}

现在我的问题是:

这是定义的行为吗?是什么阻止了编译器摆脱对 ping_pong 的任何访问,因为它看不到设置它的内容?

至少对于当前的 gcc 编译器,它似乎 可以工作:godbolt

最佳答案

我手头没有任何硬性答案,但乍一看,我会假设因为 ping_pong 是全局的,它有外部链接,因此编译器无法在那个翻译单元中优化它。

编译器不知道它将从那个 TU 中的什么地方写入,但是,当最终将所有 TU 链接在一起(对于应用程序)时,我会假设如果仍然不使用该对象可能会被丢弃。如果这段代码被编译成一个库,编译器将保持这个全局对象不变,因为它不知道外部代码是否会使用它。

==

我破解了你的代码以在 main 中创建 ping_pong,并调用:isrX(ping_pong[y]),它在 clang 上,导致包括 ping_pong 在内的大部分代码在 clang 上被优化掉。这似乎表明外部链接正在保持 ping_pong,而不是端口是易变的/从源自 ping_pong 数组的数据写入端口。

正如您所注意到的,在 GCC 上,代码保持完整,这可能暗示这是未定义的行为。存在另一种可能性,对于 GCC,编译器可能会检测到修改任何导致更新 volatile 端口的源变量将不会剔除这些源变量。

关于c++ - DMA 的同步要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63090625/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com