使用 Codec Engine 的 API 函數(五)

 本文翻譯自TI的手冊,該手冊是學習GPP+DSP開發的金典文檔,希望對各位入門有所幫助,有理解不當之處望請賜教。

 Codec Engine Application Developer User's Guide.pdf (Literature Number: SPRUE67D)

《Codec Engine 應用開發使用手冊》             http://blog.csdn.net/dyzok88/article/details/42154487

《第一章 Codec Engine 概要》                  http://blog.csdn.net/dyzok88/article/details/42214813

《第二章 Codec Engine 安裝和設置》            http://blog.csdn.net/dyzok88/article/details/42278109

《第三章 使用 Codec Engine 的示例應用程序》    http://blog.csdn.net/dyzok88/article/details/42302793

《第四章 使用 Codec Engine 的 API 函數 (一)》http://blog.csdn.net/dyzok88/article/details/42323123

《第四章 使用 Codec Engine 的 API 函數 (二)》http://blog.csdn.net/dyzok88/article/details/42324061

《第四章 使用 Codec Engine 的 API 函數 (三)》http://blog.csdn.net/dyzok88/article/details/42344661

《第四章 使用 Codec Engine 的 API 函數 (四)》http://blog.csdn.net/dyzok88/article/details/42353141


// 正文


4.5 發生什麼 DSP 內存問題?

通過 Codec Engine 提供的創建和刪除算法的 VISA API 函數,可以管理所有的算法資源。這包括CPU,內存,直接存儲器存取( DMA ),等等。VISA 的創建和刪除的 API 隱藏了大部分的編解碼器的內存和資源管理的細節。


4.5.1 緩衝處理和共享內存映射

處理所有的 I/O 和緩存的問題是應用程序的責任。控制功能的 API 函數使用指針指向 XDM_BufDesc 類型的輸入和輸出緩衝器,XDM_BufDesc 結構體如下:

typedef struct XDM_BufDesc {
    XDAS_Int8    **bufs;    
    XDAS_Int32   numBufs;  
    XDAS_Int32   *bufSizes; 
} XDM_BufDesc;

你必須把它指向的緩衝區放在 GPP 和 DSP 共享的內存區域,這摒棄了從 GPP 到 DSP 傳輸大量的信號數據和回傳數據所造成的過高的性能影響。

此外,您使用的共享數據緩衝區必須是連續的和高速緩存對齊的。

例如,DM644x 的默認內存映射的設計意圖是,爲 DSP 代碼和數據提供大量的內存空間,爲 DSP 算法提供大量的私有堆,爲 GPP 與 DSP 之間的共享緩存區提供更大的空間。

Table 4–3  DM644x Default Memory Map

4.5.2 內存碎片

對於雙 CPU 的應用程序,例外的是 Codec Engine 隱藏來自 GPP 應用程序開發人員的 DSP 內存管理問題,緩衝區傳遞到 DSP 必須是連續的物理內存和高速緩存對齊。

這不同於 GPP 的緩衝區處理,因爲 Linux 和類似的 GPP 操作系統通過存儲器管理單元( MMU )來處理非連續緩衝區,MMU 持有匹配虛擬地址到物理地址的映射表,然而 DSP 沒有這樣的表。

Codec Engine 驗證這些約束條件在數據緩衝區所需的平臺得到滿足,算法緩衝區由 Memory_module 管理,Memory_module 使用不同大小的池,確保內存不是成碎片的。

然而,由 Codec Engine 創建的編解碼器實例的存儲空間,也必須是連續的,高速緩存對齊的。編解碼器實例的創建和刪除是非確定性的。例如,如果你的應用程序遵循類似於圖4-1的步驟,它可能無法重新創建被更早創建和刪除的一個編解碼器的實例。

Figure 4–1  Non-Deterministic Buffer Creation and Deletion

因爲創建實例發生在“後臺”,而其它編解碼器在更高的優先級運行,你不能保證按所需的時間創建一個實例。但是,你可以控制創建和刪除實例的順序。

如果編解碼器或共享緩衝器不是物理上連續,當主叫方爲了獲得布爾 *isContiguous 參數,使用非 NULL 指針調用 Memory_getBufferPhysicalAddress() 函數,Codec Engine 設置指針( ptr )數據爲真或假,但不打印任何消息。如果該指針爲 NULL(這是最有可能的,因爲該函數被 codec stubs 調用,codec stubs 傳遞 NULL 給該指針),優先級爲7的跟蹤消息是:

Memory_getBufferPhysicalAddress> ERROR: user buffer at 
addr=<hex addr>, size=<size in bytes> is NOT contiguous

僅在優先級爲7時啓用跟蹤時此消息才被打印出來,這是默認的。

4.5.3 緩存對齊

利用高速緩存的設備(例如,C64+)還要求 I/O 緩衝區是緩存對齊的。例如,在 C64x+ 上的 DSP L2 cache line 的大小是128 bytes。分配存儲空間,必須從 cache line 邊界開始,大小必須爲 cache line 長度的倍數。

如果這些對齊和大小的限制被侵犯,分配到與應用緩衝區相鄰的任何數據對象,將與應用程序緩衝區的一部分共享一個 cache line。當高速緩衝存儲器控制器( Cache Controller )回寫共享的 cache line,後果可能是這條線會被破壞。


4.5.4 Cache一致性

當開發用於多處理器平臺的應用程序(包括那些具有多個處理核,硬件加速器和 DMA 引擎),其中某些內存區域被緩存,您必須執行一些內存操作的一致性。當 Codec Engine 框架有足夠的信息,將自動處理一些高速緩存一致性操作。然而,應用程序開發者最終負責確保一定的預處理和後處理的條件得到滿足,即緩衝區的應用程序的提交和 Codec Engine 的接收。

後面的小節總結了針對不同的處理器環境,應用程序開發人員的責任。


4.5.4.1 GPP + DSP 環境

下面是達芬奇( DaVinci )環境中的常見的問題,它們存在於任何利用緩存的多核系統。

請注意,Codec Engine 框架在VISA API 的實現中,強制執行其中的一些規則。使用 VISA API 函數訪問共享內存時,你應該知道這些規則。

1. Input Buffers. 這是當一個 GPP 應用程序捕獲/生成一個緩衝區並把它傳遞給DSP的情況。

(1) GPP side. 在每個 process/control 調用之前,Input buffers必須被寫回。(否則, DSP CPU/DMA 在外部存儲器中訪問的數據不連貫,沒有寫回 GPP 端緩存的能力)。如果緩衝區沒有被緩存在 GPP 端,不需要寫回( writeback )。

當驅動程序填充GPP緩存輸入緩衝區,並在傳送給 Codec Engine之前,驅動程序應該做到以下幾點:

1) 開始於緩存無效緩衝區。

2) 驅動程序可以使用 DMA 或 CPU 寫入,進而填充緩衝區。

3) 如果 CPU 被用來填充緩衝區,CPU 在傳遞緩衝區給 Codec Engine 以前必須寫回。

(2) DSP side. 在每個 process/control 調用之前, Input buffers 必須無效。(否則, DSP 可以讀取它的緩存區中的過期數據,如果在相同的緩衝區傳入較早的調用,這是可能發生的)。注意,在調用算法的處理功能之前,VISA API 函數的默認框架自動失效輸入緩衝區。

2. Output Buffers.

(1) GPP side. 遵循 DSP-side 過程,在 GPP 端訪問他們, Output buffers 必須無效。(否則, GPP 可能讀取它的 GPP-side 緩存區中的過期數據)。注意,在調用算法的處理功能之前,VISA API 函數的默認框架自動失效輸入緩衝區。如果緩衝區沒有被緩存在 GPP 端,不需要無效( invalidation )。

(2) DSP side. 在每個 process/control 調用之前, output buffers 必須無效。(否則, 如果 DMA 用於填充緩衝區,也有可能被改寫爲由於 CPU 不相關的活動而被驅逐的高速緩存線(cache lines)。並且,在每個 process/control 調用之後,output buffers必須被寫回。(否則,GPP 可能從外部存儲器讀取的數據不連貫。)注意,VISA API 函數跟隨每個 process/control 調用自動回寫 output buffers。

3. DMA-Related. 如果 GPP 或 DSP 採用 DMA 訪問共享緩衝區,爲確保一致性,還有更多的工作要做。xDAIS 爲框架提供了一些DMA規則。有關詳細信息,參見 TMS320 DSP Algorithm Standard Rules and Guidelines (SPRU352)。

C6000 算法不能在參與 DMA 傳輸的外部存儲器中,發出任何 CPU 讀取/寫入命令給緩衝區。這也適用於通過它算法接口傳遞算法的輸入緩衝區( input buffers )。

一些常見的緩存相關的錯誤有

1. DSP“輸入”("before")緩衝區是回寫-無效的緩存區( cache ),而不是隻是一個 process/control 調用“之前”("before")的無效。在這種情況下,如果“當前”輸入緩衝區的任何數據已在“以前的” process/control 調用中被引用,那麼該緩衝區的陳舊片段可能已經駐留在 DSP 的高速緩存。來自緩存中的陳舊數據回寫會破壞“當前”輸入緩衝區。

2. 做一個盲目的 "ALL L2 Cache" 回寫-無效,而不是回寫或僅算法本身的輸入/輸出緩衝器的失效。這將爲其他算法實例造成潛在問題,其輸入/輸出緩衝區將受到影響。

3. 無效所有的 L2,將嚴重地降低所有算法實例的性能,由於導致高速緩存找不到。


4.5.4.2 單核處理器環境

以下是在 DM643x 環境下的常見問題,雖然他們存在於任何利用高速緩存的單核 CPU 系統中。

1. Input Buffers. 這是當一個 DSP 應用捕獲/產生( captures/generates )一個緩衝區,並把它傳遞給 Codec Engine 的情況。取決於如何讓輸入緩衝器被捕獲,緩衝區必須要麼無效,要麼被回寫和無效:

(1) 如果應用程序(或驅動程序)修改使用 CPU 讀和/或寫操作的輸入緩衝區的內容,緩衝器必須回寫和無效。

(2) 如果應用程序(或驅動程序)修改使用 DMA 的輸入緩衝器的內容,然後該緩衝區必須不能被回寫,但仍必須被無效。

在這兩種情況下,應用程序(或驅動程序)應該開始填充一個高速緩存無效( cache-invalidated )緩衝區。

2. Output Buffers. 輸出緩衝區(被 Codec Engine 填滿)在被提交到 Codec Engine 填寫之前必須使其失效。並且,在從 Codec Engine 返回的時候,緩衝器應該被回寫,以確保所有數據被寫入到外部存儲器中。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章