掙扎許多,還是決定試著解釋看看,希望有人可以看懂,如果有不懂的,可以留言給我,或是寫信來討論。
做為一個數位設計工程師,必須有一個觀念,那就是在數位訊號處理過程中,訊號不會無中生有。必須要有人給你訊號,然後你才能做事。而這時,就會有生產者的角色產生。有了生產者,當然就必須要有消費者來消費。在這生產-消費的過程中,產生了讀寫動作,造成許許多多讀寫順序的問題。也讓我們知道「資料前後一致性(consistent view of data)」的觀念在系統中扮演的角色是有多重要了。
在生產者與消費者的模型裏我們要探討的是:
1. 生產者與消費者的順序觀念(the ordering of producer and consumer)
2. 資料的前後一致性的觀念( the consistent view of data)
Fig1: producer and consumer |
假設,有一個生產者,一個消費者。生產者想把生產出來的資料存入data buffer中,它必須先確定是否data buffer沒有正在被讀,或是完全沒有被讀過?當生產者在寫入時,flag會被設定為1,而當寫完時,status會被清除為0。當消費者要讀出來時,必須先確定是否data buffer沒有正在被寫或是完全沒有被寫過。當消費者在讀出時,flag會被消除為0,而當讀完時,status會被設定為1。經由這些動作,我們可以確保資料不會被覆寫,也不會被覆讀。flag和status的做法的概念是很好的基礎觀念,值得我們拿來借鏡,應用在設計資料存取的一致性,尤其是設計hardware和firmware在對同一塊資料存取時,是一個很好用的方法。
如Fig1所示,當生產者和消費者都是在同一個bus(匯流排)時,讀寫動作是簡單,不會有任何的問題。但是如果生產者和消費者是如Fig2所示,讀寫動作就不再是單純的。這時就產生了優先順序的問題,不然就會有死結(dead lock)的情況產生。
Fig2: complex producer and consumer |
如果生產者已經讀過 flag 和 status,想確定目前data內的資料是否是舊的,所以發出一筆讀status命令給Bridge。同時,消費者正在讀資料回來,所以發出一筆讀data的命令給Bridge。Bridge同時接受兩個不相同方向的命令,放入buffer中,接著對收入的命令的目地端的匯流排發出要求,來完成所被托付的任務。但是此時,生產者佔住了它自已的bus,而消費者也佔了它自己的bus,而在Bridge兩端的命令都無法被執行,因為它沒有拿到使用bus的權限。此時,生產者無法完成它的動作,因為消費端的bus它無法取得使用權,所以命令被卡在Bridge,下不去。消費者也無法得到它想要的data,因為它的命令也同樣是被卡在生產端的bus,無法執行。這時該怎麼辦?或許你會想,那就做一個timer,如果等 timeout,就重新執行。就可以解決死結的問題。這樣子的方式,確實可以解決死結。但是,如果每次都需要重新開始,每次開始的時間點都是一樣的,那麼是不是每次都會遇到死結的情形都會發生。這時,我們就遇到另外一個問題-飢餓狀態(starvation),這又是另一個問題的產生。
亦或者你會想要把兩邊的 timer 設成不一樣長,這樣子是不是就有機會可以解?是的,但是這樣子的做法有效率嗎?遇到死結->等 timeout ->遇到死結 -> 等 timeout ->終於沒有死結。這種把問題丟給「機率」解決,似乎不是很好的辦法。如果我們把每個命令制定優先順序,我們就可以試著找到一種順序來解決所有的死結問題。
所以,制定一個「命令的優先順序」就變得很重要。但優先順序要怎麼制定?才可以保有效率,也可以保持資料前後一致性的特性,不會造成資料存取的錯誤。這又是另一個大篇長論,請容我賣個關子,待下回分解 !
所以,制定一個「命令的優先順序」就變得很重要。但優先順序要怎麼制定?才可以保有效率,也可以保持資料前後一致性的特性,不會造成資料存取的錯誤。這又是另一個大篇長論,請容我賣個關子,待下回分解 !
沒有留言:
張貼留言