SVT-AV1編碼器中實現WPP依賴管理核心調度

assign_enc_dec_segments 函數。這個函數是 SVT-AV1 編碼器中實現波前并行處理(WPP)分段依賴管理的核心調度器之一。

//函數功能:分配編碼解碼段任務

//返回值Bool

//True 成功分配了一個段給當前線程,調用者應該處理這個段

//False 當前沒有可立即處理的段,調用這個應該跳出循環或者進行其他操作

參數:

//segmentPtr: 指向EncDecSegments 結構的指針,包含整個圖像分段的狀態,依賴關系等信息

//segmentInOutIndex 輸入輸出參數,輸入時可能是舊的段索引,輸出時,如果分配成功,被設置為分配段的索引。

//taskPtr 指向EncDecTasks結構體的指針,包含任務的具體信息

srmFifoPtr 指向一個FIFO隊列指針,用于在需要時向其他現線程反饋新的任務。

static Bool assign_enc_dec_segments(EncDecSegments *segmentPtr, uint16_t *segmentInOutIndex, EncDecTasks *taskPtr, EbFifo *srmFifoPtr)

{

//初始化標志位,表示是否成功分配了段以供繼續處理

Bool continue_processing_flag = FALSE;

//當前段所在的行索引

uint32_t row_segment_index = 0;

//當前正在處理或者檢查的段索引

uint32_t segment_index;

//當前段的右鄰居 段索引

uint32_t right_segment_index;

//當前段的左下鄰居段索引,在WPP依賴中非常重要

uint32_t bottom_left_segment_index;

//反饋行索引,初始化為-1表示暫無反饋需要返送

//如果不為-1 ,則表示需要向指定行反饋一個任務

int16_t feedback_row_index = -1;

//標志位,表示在當前函數調用中是否已經為當前線程自身分配了一個段

//用于防止一次調用分配多個段給同一個線程

uint32_t self_assigned = FALSE;

//根據輸入任務的任務類型 input_type 進行不同的處理

switch (taskPtr->input_type)

{

//case 1 任務來自MDC, Mode Decision Configuration 過程輸入

case ENCDEC_TASKS_MDC_INPUT:

//整個圖像的MDC過程已經完成,提供了完整的畫面信息

//因此不需要復雜的邏輯來清除輸入依賴

//重置所有編碼解碼段的行狀態:遍歷每一行分段

for (uint32_t row_index = 0; row_index < segmentPtr->segment_row_count; ++row_index) {

//將美航的當前處理段索引重置為該行的起始段索引

segmentPtr->row_array[row_index].current_seg_index = segmentPtr->row_array[row_index].starting_seg_index;

}

//立即從第0行的第0個段開始處理

*segmentInOutIndex = segmentPtr->row_array[0].current_seg_index;//分配段索引

taskPtr->input_type = ENCDEC_TASKS_CONTINUE;//將任務類型標記為 繼續 以便后續處理

//遞增第0行的當前段索引,為下一次分配做準備

++segmentPtr->row_array[0].current_seg_index;

//設置標志位TRUE,表示成功分配了段,調用者應繼續處理此段

continue_processing_flag = TRUE;

break; //跳出siwtch

//case 2:任務指定了要處理的編碼解碼行ENCDEC_INPUT

case ENCDEC_TASKS_ENCDEC_INPUT:

//立即從指定行enc_dec_segment_row 的當前段開始處理

*segmentInOutIndex = segmentPtr->row_array[taskPtr->enc_dec_segment_row].current_seg_index;

taskPtr->input_type = ENCDEC_TASKS_CONTINUE;//將任務類型標記為繼續

//遞增指定行的當前段索引

++segmentPtr->row_array[taskPtr->enc_dec_segment_row].current_seg_index;

//設置標志位為True,表示成功分配了段

continue_processing_flag = TRUE;

break;

//任務類型是繼續COnitnue,表示一個段已經完成處理,需要檢查并更新依賴關系,可能分配下一個段。

case ENCDEC_TASKS_CONTINUE:

//獲取剛剛處理完的段索引

segment_index = *segmentInOutIndex;

//計算這個段所在的行索引 將一維段索引映射到二維的行索引

tow_segment_index = segment_idnex / segmentPtr->segment_band_count;

//計算當前段的右鄰居段索引 同一行,下一個段

right_segment_index = segment_idnex + 1;

//計算當前段的左下鄰居段索引,相對左下位置,這是WPP依賴的關鍵

bottom_left_segment_index = segment_idnex + segmentPtr->segment_band_count;

//檢查并處理右鄰居段的依賴

//首先檢查右鄰居是否存在,當前段索引是否小雨當前行的結束段索引

if (segment_index < segmentPtr->row_array[row_segment_index].assignment_mutex) {

//遞減右鄰居段的依賴計數器,每個段初始時間能有依賴,例如依賴于左上和上方的段

--segmentPtr->dep_map.dependency_map[right_segment_index];

//檢查右鄰居段的依賴計數器是否降為0, 意味著它所依賴的所有段都已經處理完成

if (segmentPtr->dep_map.dependency_map[right_segment_index] == 0) {

//依賴已滿足,可以將右鄰居段分配給當前線程處理

*segmentInOutIndex = segmentPtr->row_array[row_segment_index].current_seg_index;

//遞增該行的當前段索引,為下次分配準備

++segmentPtr->row_array[row_segment_index].current_seg_index;

//標記當前線程已經為自己分配了一個段

self_assigned = TRUE;

//設置標志位,表示有段需要處理

continue_processing_flag = TRUE;

}

//釋放當前的互斥鎖

svt_release_mutex(segmentPtr->row_array[row_segment_index].assignment_mutex);

}

//檢查并處理左下鄰居段的依賴

//檢查左下鄰居是否存在1 當前行不是最后一行,2 左下鄰居段索引在該下一行的有效范圍內

if (row_segment_index < segmentPtr->segment_row_count - 1 && bottom_left_segment_index >= segmentPtr->row_array[row_segment_index + 1].starting_seg_index) {

//獲取下一行的互斥鎖,以安全的修改該行的共享依賴狀態

svt_block_on_mutex(segmentPtr->row_array[row_segment_index + 1].assignment_mutex);

//遞減左下鄰居段的依賴計數器是是否降為0

if (segmentPtr->dep_map.dependency[bottom_left_segment_index] == 0) {

//如果當前線程在檢查右鄰居時已經在自身分配了一個段

if (self_assigned == TRUE)

//則無法同時處理左下段,記錄需要反饋的行索引 下一行

//稍后將創建一個新任務放入隊列,讓其他線程處理這個就緒的段

feedback_row_index = (int16_t)row_segment_index + 1;

else {

*segmentInOutIndex = segmentPtr->row_array[row_segment_index + 1].current_seg_index;

++segmentPtr->row_array[row_segment_index + 1].current_seg_index;

continue_processing_flag = TRUE;

}

}

//釋放下一行的互斥鎖

svtt_release_mutex(segmentPtr->row_array[row_segment_index + 1].assignment_mutex);

}

//如果之前發現左下段就緒但是自身無法處理,因為已經分配了右段,則需要反饋任務

if (feedback_row_index > 0) {

EbObjectWrapper *wrapper_ptr;

//從FIFO隊列中獲取一個空的任務包裝器對象

svt_get_empty_object(srmFifoPtr, &wrapper_ptr);

//獲取包裝器中的任務對象

EncDecTasks *feedback_task = (EncDecTasks*)wrapper_ptr->object_ptr;

//設置任務類型為ENCDEC_INPUT,并指定需要處理的行

feedback_task->input_type = ENCDEC_TASKS_ENCDEC_INPUT;

feedback_task->enc_dec_segment_row = feedback_row_index; //設置需要處理的行索引

//負值必要的上下文信息

feedback_task->pcs_wrapper = taskPtr->pcs_wrapper;

feedback_task->file_group_index = taskPtr->tile_group_index;

//將填充好的任務對象發布到FIFO隊列中,等待其他工作線程獲取并處理

svt_post_full_object(wrapper_ptr);

}

break;//跳出switch

}

default: break;

}

//返回標志位,告知調用者是否分配了段以供處理

return continue_processing_flag;

}

1 依賴管理,此函數的核心是管理圖像分段間的空間依賴關系,在視頻編碼中,處理一個編碼塊通常需要上方,左上方和右上方的塊信息。

assign_enc_dec_segments 通過一個依賴映射表dependency_map 來跟蹤每個分段對其前置分段的依賴。當一個分段處理完成是,會遞減其右鄰居和左下鄰居的依賴計數。 只有當依賴計數降為0時,該分段被認為就緒,可以背分配處理。

2 實現波前并行處理:這個函數時SVT-AV1 實現Wavefront Parallel Processing 的關鍵。WPP允許編碼器在處理第N行的幾個塊之后,可以開始處理第N+1行,不必等待整行N處理完畢,這極大的提高了多核CPU的利用率和編碼并行度。函數中bottom_left_segment_index檢查和反饋機制正是為了實現這種波浪式的推進。

3 任務調度與負載均衡:函數作為一個調度器,動態地將就緒的分配給工作現場,痛毆互斥鎖,保護共享狀態current_seg_index。確保了多線程環境下的正確性。當某個現場完成分段后,會立即嘗試獲取下一個就緒的分段,有助于保持所有CPU核心的繁忙狀態。

4 通信與同步:函數通過FIFO隊列進行現場間的通信。當一個現場發現自己觸發了另一個分段就緒,但是又無法立即處理時

self_assigned == TRUE的情況,會創建一個新的任務并放入隊列,通知其他工作線程有新的工作可用,這是一種高效的工作竊取Work Stealing和協同機制。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/95840.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/95840.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/95840.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

直接讓前端請求代理到自己的本地服務器,告別CV報文到自己的API工具,解放雙手

直接使用前端直接調用本地服務器&#xff0c;在自己的瀏覽器搜索插件proxyVerse&#xff0c;類似的插件應該還有一些&#xff0c;可以選擇自己喜歡的這類插件可以將瀏覽器請求&#xff0c;直接轉發到本地服務器&#xff0c;這樣在本地調試的時候&#xff0c;不需要前端項目&…

Golang Goroutine 與 Channel:構建高效并發程序的基石

在當今這個多核處理器日益普及的時代&#xff0c;利用并發來提升程序的性能和響應能力已經成為軟件開發的必然趨勢。而Go語言&#xff0c;作為一門為并發而生的語言&#xff0c;其設計哲學中將“并發”置于核心地位。其中&#xff0c;Goroutines 和 Channels 是Go實現并發編程的…

17 C 語言宏進階必看:從宏替換避坑到宏函數用法,不定參數模擬實現一次搞定

預處理詳解1. 預定義符號//C語?設置了?些預定義符號&#xff0c;可以直接使?&#xff0c;預定義符號也是在預處理期間處理的。 __FILE__ //進?編譯的源?件--預處理階段被替換成指向文件名字符串的指針--char* 類型的變量 __LINE__ //?件當前的?號 --預處理階段替換成使用…

深入剖析 HarmonyOS ArkUI 聲明式開發:狀態管理藝術與最佳實踐

好的&#xff0c;請看這篇關于 HarmonyOS ArkUI 聲明式開發范式與狀態管理的技術文章。 深入剖析 HarmonyOS ArkUI 聲明式開發&#xff1a;狀態管理藝術與最佳實踐 引言 隨著 HarmonyOS 4、5 的廣泛應用以及面向未來的 HarmonyOS NEXT&#xff08;API 12&#xff09;的發布&…

Qwen-Code安裝教程

一、概述Qwen Code 是一個強大的基于命令行、面向開發者的 AI 工作流工具&#xff0c;改編自 Gemini CLI&#xff0c;專門針對 Qwen3-Coder 模型進行了優化。它專門為代碼理解、代碼重構、自動化工作流、Git 操作等場景設計&#xff0c;讓你的開發工作變得更高效、更智能。它既…

老師傅一分鐘精準判斷電池好壞!就靠這個神器!

在汽車維修與保養領域&#xff0c;蓄電池狀態的準確判斷一直是技術人員面臨的重要挑戰。傳統的電壓測量方法只能反映表面現象&#xff0c;無法深入評估蓄電池的實際健康狀態。Midtronics MDX-P300蓄電池及電氣系統測試儀作為專業級診斷設備&#xff0c;通過電導測試技術和多系統…

Axure筆記

Axure介紹 快速原型的軟件 應用場景&#xff1a;拉投資、給項目團隊、銷售演示、項目投標、內部收集反饋、教學 軟件安裝與漢化 漢化&#xff1a;復制lang文件夾和三個dll 軟件的基礎功能 基本布局&#xff1a;菜單欄、工具欄、頁面和摘要、元件和母版、畫布、樣式交互和說明設…

Pytorch Yolov11 OBB 旋轉框檢測+window部署+推理封裝 留貼記錄

Pytorch Yolov11 OBB 旋轉框檢測window部署推理封裝 留貼記錄 上一章寫了下【Pytorch Yolov11目標檢測window部署推理封裝 留貼記錄】&#xff0c;這一章開一下YOLOV11 OBB旋轉框檢測相關的全流程&#xff0c;有些和上一章重復的地方我會簡寫&#xff0c;要兩篇結合著看&#x…

《Keil 開發避坑指南:STM32 頭文件加載異常與 RTE 配置問題全解決》

《Keil 開發避坑指南&#xff1a;STM32 頭文件加載異常與 RTE 配置問題全解決》文章提綱一、引言? 簡述 Keil 在 STM32 開發中的核心地位&#xff0c;指出頭文件加載和 RTE&#xff08;運行時環境&#xff09;配置是新手常遇且關鍵的問題&#xff0c;說明本文旨在為開發者提…

TortoiseGit 2.4.0.0 64位安裝教程(附詳細步驟和Git配置 附安裝包)

本教程詳細講解 ?TortoiseGit 2.4.0.0 64位版本? 的完整安裝步驟&#xff0c;包括如何運行 ?TortoiseGit-2.4.0.0-64bit.msi? 安裝包、設置安裝路徑、關聯 Git 環境&#xff0c;以及安裝后的基本配置方法&#xff0c;適合 Windows 用戶快速上手 Git 圖形化管理工具。 一、…

大數據畢業設計選題推薦-基于大數據的高級大豆農業數據分析與可視化系統-Hadoop-Spark-數據可視化-BigData

?作者主頁&#xff1a;IT畢設夢工廠? 個人簡介&#xff1a;曾從事計算機專業培訓教學&#xff0c;擅長Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等項目實戰。接項目定制開發、代碼講解、答辯教學、文檔編寫、降重等。 ?文末獲取源碼? 精彩專欄推薦?…

學習機器學習能看哪些書籍

關注B站可以觀看更多實戰教學視頻&#xff1a;hallo128的個人空間 在機器學習與深度學習的知識海洋中&#xff0c;選擇合適的書籍往往是入門和進階的關鍵。以下四本經典著作各具特色&#xff0c;覆蓋了從基礎理論到實踐應用的多個維度&#xff0c;無論你是初學者還是有一定基礎…

Unity通過Object學習原型模式

原型模式簡述 依據現有的實例生成新的實例 Object的實例化方法 Object.Instantiate 克隆 original 對象并返回克隆對象 Unity中的實例&#xff1a;預制體或場景中的游戲對象 示例 方法1&#xff1a;手動創建對象并添加組件 方法2&#xff1a;使用實例化方法&#xff0c;實…

【踩坑記錄】Unity 項目中 PlasticSCM 掩蔽列表引發的 文件缺失問題排查與解決

問題描述&#xff1a; Plastic SCM 簽入時&#xff0c;彈窗提示“項xxx在該工作區中不存在” Unity 項目中 PlasticSCM 掩蔽列表引發的 文件缺失問題排查與解決 文章目錄Unity 項目中 PlasticSCM 掩蔽列表引發的 文件缺失問題排查與解決一、前言二、Unity 與 .meta 文件機制1. …

Redis實戰-附近的人實現的解決方案

1.GEO數據結構1.1實現附近的人的數據結構Redis提供的專用的數據結構來實現附近的人的操作&#xff0c;這也是企業的主流解決方案&#xff0c;建議使用這種解決方案。GEO就是Redis提供的地理坐標計算的一個數據結構&#xff0c;可以很方便的計算出來兩個地點的地理坐標&#xff…

HTML第七課:發展史

HTML第七課&#xff1a;發展史發展史快速學習平臺發展史 示例 HTML 發展史 前端三件套&#xff1a;html 、css、javascript(Js) HTML 發展史 HTML 1.0&#xff08;1993 年&#xff09; 蒂姆伯納斯 - 李&#xff08;Tim Berners - Lee&#xff09;發明了萬維網&#xff0c;同…

中國生成式引擎優化(GEO)市場分析:領先企業格局與未來趨勢分析

一、GEO市場變革中國生成式引擎優化&#xff08;Generative Engine Optimization, GEO&#xff09;市場正經歷一場深刻的變革&#xff0c;其核心在于生成式人工智能&#xff08;Generative AI&#xff09;對傳統搜索引擎和數字營銷模式的顛覆性影響。傳統搜索引擎以“提供鏈接”…

好看的背景顏色 uniapp+小程序

<view class"bg-decoration"><view class"circle-1"></view><view class"circle-2"></view><view class"circle-3"></view> </view>/* 背景裝飾 */.container{background: linear-gr…

《駕馭云原生復雜性:隱性Bug的全鏈路防御體系構建》

容器、服務網格、動態配置等抽象層為系統賦予了彈性與效率,但也像深海中的暗礁,將技術風險隱藏在標準化的接口之下。那些困擾開發者的隱性Bug,往往并非源于底層技術的缺陷,而是對抽象層運行邏輯的理解偏差、配置與業務特性的錯配,或是多組件交互時的協同失效。它們以“偶發…

vosk語音識別實戰

一、簡介 Vosk 是一個由 Alpha Cephei 團隊開發的開源離線語音識別&#xff08;ASR&#xff09;工具包。它的核心優勢在于完全離線運行和輕量級&#xff0c;使其非常適合在資源受限的環境、注重隱私的場景或需要低延遲的應用中使用。 二、核心特點 離線運行 (Offline) 這是…