2017-02-13 108 views
0

我有一個使用USB中的兩個不同批量通道發送圖像數據和視頻幀的設備。設備驅動程序內存緩衝區處理器緩存問題

我的工作站處理器緩存有點大,足以容納大約100個視頻幀,沒有任何問題,但沒有圖像數據。

我對圖像和視頻數據使用相同的緩衝區,該緩衝區大約有50個塊,一個塊大小爲1MB。 視頻幀快速出現,然後是圖像幀。

我的問題是,在以下secnario中是否存在內存損壞問題?有人在處理器緩存知識可以幫助我。

  • 由於視頻幀很小,因此寫入視頻幀的內存緩衝區中的頁面幾乎都在緩存中。由於視頻數據以流的形式出現,因此永遠不會刷新。
  • 但是當圖像數據到來時,將使用大面積的內存緩衝區,然後視頻內存頁面將被刷新。但計劃被刷新但仍未寫入物理內存。
  • 現在圖像數據被寫入內存,我在那裏使用了volatile
  • 在寫入映像數據後刷新緩存時,數據將被緩存刷新損壞。

會發生這種情況嗎? 所以我申請了volatile來寫視頻數據,這個問題看起來好像消失了。但是我需要做一個報告,那麼上面提到的情況有可能發生嗎?

+0

不知道我是否完全理解你的問題,但我認爲你正在混淆兩個完全不相關的概念:'volatile'修飾符無法操縱CPU緩存。 volatile表示可以在CPU的控制之外修改數據。如果添加'volatile'修復某些內容,這只是意味着您的編譯器足夠聰明,可以優化代碼,如果數據僅由CPU操作,那麼代碼看起來不必要/冗餘。 – mfro

+0

是的,它來自外部,從另一個線程,然而libusb,一個用戶模式線程。 –

+0

讓我更加明確地說,如果通過添加'volatile'消除線程錯誤,那只是巧合。你不能依賴它,並且通過編寫下一行代碼可能會再次破壞它。 – MSalters

回答

1

評論是贈品:兩個線程,而volatile被誤用爲線程機制。

兩個線程可以在兩個CPU內核上運行。雖然內核通常共享內存,但它們通常不共享L1緩存。中間緩存有所不同。因此,取消引用兩個CPU內核上的相同的指針可能會給出不同的結果。這對於跨線程正確共享的變量不是問題;編譯器將使用正確的指令。但關鍵字正確共享。

在這裏,我們探討了將問題標記爲C和C++的一個小問題,因爲在線程之前分叉的兩種語言在任何一種語言中都是標準化的。但是,這兩種線程機制是故意相似的,因此編譯器對可以(作爲擴展)定義C線程和C++線程如何交互。你需要諮詢你的文檔。

它可能會更容易包裹libusb線程在自己的代碼,讓你接收數據,而不線程問題,然後從你的代碼調度。同時也是你的控制下的其他線程。

回到你看到的內存損壞:你可能看到的是一個線程正在寫出它的內存視圖,結果是它的緩存中陳舊的數據。如果你使用了類似互斥體的東西,這個陳舊的數據會被記錄下來並且緩存同步。

+0

嗨,我不明白爲什麼易失性指針解除引用不能解決問題? –

+0

我不需要一個線程來發信號給其他線程,因爲我可以保證它們會按順序發生。 libusb的實現已經爲我做了。我還需要像C++概念那樣使用互斥鎖嗎? –