【问题标题】:device driver memory buffer processor cache issue设备驱动程序内存缓冲区处理器缓存问题
【发布时间】:2017-07-01 01:18:33
【问题描述】:

我有一个设备,它使用 USB 中的两个不同的批量通道发送图像数据和视频帧。

我的工作站处理器缓存有点大,足以容纳大约 100 个视频帧而没有任何问题,但不能容纳图像数据。

我对图像和视频数据使用相同的缓冲区,该缓冲区有大约 50 个块,一个块大小为 1MB。 视频帧来得很快,然后是图像帧。

我的问题是,以下 secnario 中是否存在内存损坏问题?有处理器缓存知识的人可以帮助我。

  • 由于视频帧很小,内存缓冲区中写入视频帧的页面几乎都在缓存中。由于视频数据以流的形式出现,因此它永远不会被刷新。
  • 但是当图像数据到来时,内存缓冲区的大面积将被使用,然后视频内存页面将被刷新。但计划刷新但仍未写入物理内存。
  • 现在图像数据已写入内存,我在那里使用了volatile。
  • 并且在图像数据写入后刷新这些数据时,缓存刷新会损坏这些数据。

这会发生吗? 所以我也将volatile 应用于视频数据写入,这个问题看起来就消失了。但是我需要做一个报告,那么上面提到的这种情况有可能发生吗?

【问题讨论】:

  • 不确定我是否完全理解您的问题,但我假设您混淆了两个完全不相关的概念:volatile 修饰符无法操作 CPU 缓存。 volatile 只是说数据可能会在 CPU 控制之外被修改。如果添加 volatile 可以解决问题,这仅意味着您的编译器足够聪明,可以优化代码,如果数据仅由 CPU 处理,则这些代码似乎不必要/冗余。
  • 是的,它来自外部,来自另一个线程,但是 libusb,一个用户模式线程。
  • 让我说得更清楚一点,如果线程错误通过添加volatile 消失,那只是巧合。你不能依赖它,写下一行代码可能会再次崩溃。

标签: c++ c caching memory volatile


【解决方案1】:

cmets 是赠品:两个线程,volatile 被误用作线程机制。

两个线程可以在两个 CPU 内核上运行。虽然内核通常共享内存,但它们通常不共享 L1 缓存。中间缓存有所不同。因此,在两个 CPU 内核上取消引用 same 指针可能会产生不同的结果。对于跨线程正确共享的变量,这不是问题;编译器将使用正确的指令。但是关键字是正确共享的。

在这里,我们遇到了一个小问题,即您已将问题标记为 C 和 C++,因为这两种语言在线程被标准化之前就已经分叉了。但是,这两种线程机制有意相似,因此编译器对可以(作为扩展)定义 C 线程和 C++ 线程如何交互。为此,您需要查阅您的文档。

将libusb 线程包装在您自己的代码中可能更容易,这样您就可以在没有线程问题的情况下接收数据,然后从您的代码分派到同样在您控制之下的其他线程。

回到您看到的内存损坏:您可能看到的是一个线程正在写出它的内存视图,结果证明它是缓存中的陈旧数据。如果您使用了诸如互斥锁之类的东西,那么这些过时的数据就会被记录下来并同步缓存。

【讨论】:

  • 嗨,我不明白为什么 volatile 指针取消引用不能解决问题?
  • 我不需要一个线程来给另一个线程发信号,因为我可以保证它们会按顺序发生。 libusb 实现已经为我做到了。我还需要像 C++ 概念那样使用互斥锁吗?
猜你喜欢
  • 1970-01-01
  • 2016-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
  • 2018-06-25
  • 2014-09-07
  • 2017-06-30
相关资源
最近更新 更多