分配器

分配器

分配器,外文名:allocator,機電業}名詞,是有線電視傳輸系統中分配網路里最常用的部件,用來分配信號的部件。在C++編程中,分配器(英語:allocator)是C++標準庫的重要組成部分。C++的庫中定義了多種被統稱為“容器”的數據結構(如鍊表、集合等),這些容器的共同特徵之一,即是其大小可以在程式的運行時改變;為了實現這一點,進行動態記憶體分配就顯得尤為必要,在此分配器就用於處理容器對記憶體的分配與釋放請求。換句話說,於分配器用封裝STL容器在記憶體管理上的低層細節。默認情況下,C++標準庫使用其自帶的通用分配器,但根據具體需要,程式設計師也可自行定製分配器以替代之。

簡介

分配器是 有線電視傳輸系統中分配網路里最常用的部件,用來分配信號的部件。分配器最早由亞歷山大·斯特潘諾夫作為C++標準模板庫(StandardTemplateLibrary,簡稱STL)的一部分發明,其初衷是創造一種能“使庫更加靈活,並能獨立於底層數據模型的方法”,並允許程式設計師在庫中利用自定義的指針和引用類型;但在將標準模板庫納入C++標準時,C++標準委員會意識到對數據模型的完全抽象化處理會帶來不可接受的性能損耗,為作折中,標準中對分配器的限制變得更加嚴格,而有鑒於此,與斯特潘諾夫原先的構想相比,現有標準所描述的分配器可定製程度已大大受限。
雖然分配器的定製有所限制,但在許多情況下,仍需要用到自定義的分配器,而這一般是為封裝對不同類型記憶體空間(如共享記憶體與已回收記憶體)的訪問方式,或在使用記憶體池進行記憶體分配時提高性能而為。除此以外,從記憶體占用和運行時間的角度看,在頻繁進行少量記憶體分配的程式中,若引入為之專門定製的分配器,也會獲益良多。

功能

它的功能是將一路輸入信號均等地分成幾路輸出,通常有二分配、三分配、四分配、六分配等。 有線電視網的頻率不斷提升,功能不斷加強,因此對分配器的要求不斷提高。
在接口設備上分配器是將音視頻信號分配至多個顯示設備或投影顯示系統上的一種控制設備。它是專門分配信號的接口形式的設備。分配器具有一個顯著的特點就是,可以將高清AV信號通過普通的同軸電纜線延長到200米左右,能徹底解決工程中因信號信號源1個而顯示設備有多個種類與數量而造成的問題。
用戶使用時先將信號通過一根標配的高質量線引接到分配器的INPUT上,分配器上有兩個或者四個甚至多個輸出口,其中可以接到本地顯示器上,其他的可以接到遠端的顯示設備上,通過調節分配器上的亮度和對比度,就可以把遠端顯示設備的圖像清晰度調整到與本地一樣的效果。通過調整後,遠端顯示設備的圖像質量會有質的提高,分配器可以最大程度的消除脫尾和重影現象,完全可以滿足目前我國各種重點工程對高品質圖像質量的要求。

技術指標

1、頻率範圍:分配器使用在整個有線電視網中,因此應具有寬頻的 頻率特性; 輸入輸出阻抗:有線電視網中的射頻各種接口阻抗均應為75歐,以實現阻抗匹配,因此分配器輸入端及輸出端阻抗均應為75歐;
2、分配損失:在系統中總希望接入分配器損耗越小越好。分配損失Ls的多少和分配路數n的多少有關,在理想情況下Ls=10lgn,當n=2時為二分配器分配損失為3dB。實際上除了等分信號的損失外,還有一部分是由於分配器件本身有衰減,所以總比計算值要大。如在550-750MHz時二分配器分配損失工程上常取值3.5dB,4分配器損失常取值8dB;
3、相互隔離:相互隔離亦稱分配隔離。如果在分配器的某一個輸出端加入一個信號,該信號電平與其它輸出端該信號電平之差即是相互隔離,一般要求分配器輸出端隔離度大於20dB以上。如果駐波比太大,則傳輸信號就會在分配器的輸入端或者輸出端產生反射,對圖像質量產生不良影響,如重影等。 分配器在工程中還分為過電型分配器、戶外型分配器、戶內分配器等。
4、駐波比:全稱為電壓駐波比,又名VSWR和SWR,為英文Voltage Standing Wave Ratio的簡寫。
駐波比就是一個數值,用來表示 天線和電波發射台是否匹配。如果 SWR 的值等於1, 則表示發射傳輸給天線的電波沒有任何反射,全部發射出去,這是最理想的情況。如果SWR 值大於1, 則表示有一部分電波被反射回來,最終變成熱量,使得饋線升溫。被反射的 電波在發射台輸出口也可產生相當高的電壓,有可能損壞發射台。
5、反射損耗 是指負載直接接在信號源上所得到的功率和由於分配器匹配不好引起的反射功率之比 用dB表示
6、射頻特性

產品分類

(1)A型分配器、G型分配器、M型分配器、F型分配器叫做板式分配器,其中A型90%用於國內。、
(2)D型分配器、S型分配器、U型分配器叫做井式分配器,其中S型分配90%用於國內
美洲和歐洲產品的區別:美標的帶安全閥,但是歐標德沒有。
產品詳細說明:
1、部件:小桶連線器(板式,井式分配器)、啤酒龍頭,啤酒塔,酒矛,啤酒扎啤機,酒標。
2、本產品與啤酒扎啤機、啤酒龍頭,啤酒塔,酒矛,制冷機,酒標配套使用,通過小桶連線器和酒矛的作用將啤酒送入啤酒扎啤機,經扎啤機製冷,混合閥閥門打開。打開二氧化碳壓力表,使二氧化碳壓入酒桶,啤酒從出酒龍頭放出。產品設計精湛,擺設大方,文明衛生,使用方便,隨時飲用。是酒吧,賓館,餐廳,客廳等需喝扎啤的理想用品。
3、設計精湛,擺設大方,文明衛生,使用方便,隨時飲用。

使用需求

分配器分配器
任意滿足分配器使用需求的C++類都可作分配器使用。具體來說,當一個類(在此設為類A)有為一個特定類型(在此設為類型T)的對象分配記憶體的能力時,該類就必須提供以下類型:A::pointer(指針),A::const_pointer(常量指針),A::reference(引用),A::const_reference(常量引用)及A::value_type(值類型),如此才能以通用的方式聲明對象與對該類對象的引用T。allocator提供這些指針或引用的類型定義的初衷,是隱蔽指針或引用的物理實現細節;因為在16位編程時代,遠指針(farpointer)是與普通指針非常不同的,allocator可以定義一些結構來表示這些指針或引用,而容器類用戶不需要了解其是如何實現的。同時類A還需提供類型A::size_type(表示所用記憶體大小的類型)與A::difference_type(指針差值的類型),其中size_type類型是用於表示類A所定義的分配模型中的單個對象最大尺寸的無符號整型,而difference_type類型是帶符號整型,用於表示分配模型內的兩個指針的差異值。
雖然按照標準,在庫的實現過程中允許假定分配器(類)A的A::pointer(指針)與A::const_pointer(常量指針)即是對T*與Tconst*的簡單的類型定義,但一般更鼓勵支持通用分配器。
另外,設有對於為某一對象類型T所設定的分配器A,則A必須包含四項成員函式,分別為分配函式、解除分配函式、最大個數函式和地址函式。分配函式用以進行記憶體分配,形如A::pointerA::allocate(size_typen,A<void>::const_pointerhint=0)。其中調用參數n即為需要分配的對象個數,另一調用參數hint(須為指向已為A所分配的某一對象的指針)則為可選參數,可用於在分配過程中指定新數組所在的記憶體地址,以提高引用局部性,但在實際的分配過程中程式也可以根據情況自動忽略掉該參數。該函式調用時會返回指向分配所得的新數組的第一個元素的指針,而這一數組的大小足以容納n個T類元素。在此需要注意的是,調用時只為此數組分配了記憶體,而並未實際構造對象
解除分配函式形如voidA::deallocate(A::pointerp,A::size_typen)。其中p為需要解除分配的對象指針(以A::allocate函式所返回的指針做參數),n為對象個數,而調用該函式時即是將以p起始的n個元素解除分配,但同時並不會析構之。C++標準明確要求在調用deallocate之前,該地址空間上的對象已經被析構。
最大個數函式形如A::max_size(),調用時返回調用一次分配函式A::allocate所能成功分配的元素的最大個數,其返回值等價於A::size_type(-1)/sizeof(T)的結果。
地址函式形如A::pointerA::address(referencex),調用時返回一個指向x的指針。
除此以外,由於對象的構造/析構過程與分配/解除分配過程分別進行,因而分配器還需要成員函式A::construct(構造函式)與A::destroy(析構函式)以對對象進行構造與析構,且兩者應等價於如下函式:
template<typenameT>voidA::construct(A::pointerp,A::const_referencet){new((void*)p)T(t);}template<typenameT>voidA::destroy(A::pointerp){((T*)p)->~T();}
以上代碼中使用了placementnew語法,且直接調用了析構函式。
分配器應是可複製構造的,任舉一例,為T類對象而設的分配器可由另一為U類所設的分配器構造。若某分配器分配了一段存儲空間,則這段存儲空間只能由與該分配器等價的分配器解除分配。分配器還需要提供一個模板類成員函式template<typenameU>structA::rebind{typedefA<U>other;};,以模板(C++)參數化的方式,借之來針對不同的數據類型獲取不同的分配器。例如,若給定某一為整型(int)而設的分配器IntAllocator,則可執行IntAllocator::rebind<long>::other以獲取對應長整型(long)的相關分配器。實際上,stl::list<int>實際要分配的是包含了雙向鍊表指針的node<int>,而不是實際分配int類型,這是引入了rebind的初衷。
與分配器相關聯的operator==,僅當一個allocator分配的記憶體可以被另一個allocator釋放時,上述相等比較算符返回真。operator!=的返回結果與之相反。

自定義

分配器分配器
自定義分配器的主要原因之一是提升性能。利用專用的自定義分配器可以提高程式的性能,又或提高記憶體使用效率,亦或兩者兼而有之。默認分配器使用new操作符分配存儲空間,而這常利用C語言堆分配函式(malloc())實現。由於堆分配函式常針對偶發的記憶體大量分配作最佳化,因此在為需要一次分配大量記憶體的容器(如矢量、雙端佇列)分配記憶體時,默認分配器一般效率良好。但是,對於映射表與雙向鍊表這類需要頻繁分配少量記憶體的容器來說,若採用默認分配器分配記憶體,則通常效率很低。除此之外,基於malloc()的默認分配器還存在許多問題,諸如較差的引用局部性,以及可能造成記憶體碎片化。有鑒於此,在這一情況下,人們常使用基於記憶體池的分配器來解決頻繁少量分配問題。與默認的“按需分配”方式不同,在使用基於記憶體池的分配器時,程式會預先為之分配大塊記憶體(即“記憶體池”),而後在需要分配記憶體時,自定義分配器只需向請求方返回一個指向池內記憶體的指針即可;而在對象析構時,並不需實際解除分配記憶體,而是延遲到記憶體池的生命周期完結時才真正解除分配。
在“自定義分配器”這一話題上,已有諸多C++專家與相關作者參與探討,例如斯科特·梅耶斯的作品《EffectiveSTL》與安德烈·亞歷山德雷斯庫的《ModernC++Design》都有提及。梅耶斯洞察到,若要求某一分配器的所有實例等效,則可移植的分配器必須不包含狀態。雖然C++標準鼓勵庫的實現者支持帶狀態的分配器,但梅耶斯稱,相關段落是“(看似)美妙的觀點”,但也幾乎是空話,並稱分配器的限制“過於嚴苛”。
另外,在《C++程式設計語言》中,比雅尼·史特勞斯特魯普則認為“‘嚴格限制分配器,以免各對象信息不同’,這點顯然問題不大”(大意),並指出大部分分配器並不需要狀態,甚至沒有狀態時性能反倒更佳。他提出了三個自定義分配器的用例:記憶體池型的分配器、共享記憶體型分配器與垃圾回收型分配器,並展示了一個分配器的實現,此間利用了一個內部記憶體池,以快速分配/解除分配少量記憶體。但他也提到,如此最佳化可能已經在他所提供的樣例分配器中實現。
自定義分配器的另一用途是調試記憶體相關錯誤。若要做到這一點,可以編寫一個分配器,令之在分配時分配額外的記憶體,並藉此存放調試信息。這類分配器不僅可以保證記憶體由同類分配器分配/解除分配記憶體,還可在一定程度上保護程式免受快取溢出之害。

使用方法

當初始化標準容器時,若需使用自定分配器,則可將其寫入模板參數,以代替默認的std::allocator<T>,如下所示:namespacestd{template<classT,classAllocator=allocator<T>>classvector;//...
正如其他所有C++類模板般,在初始化同一標準庫容器時,若使用了不同的分配器,則所生成容器的類型亦不同。譬如,若函式需一整型矢量數組std::vector<int>作為參數,則其只能接受由默認分配器生成的整型矢量數組。
C++11
通過加入“作用域”分配器,C++11標準進一步強化了分配器接口,從而保證帶有嵌套式記憶體分配特點的容器(如字元串矢量數組等)所分配到的記憶體皆來自容器自身的分配器。
另外,C++11標準刪除了“給定類型的分配器在比較時總是相等”的模稜兩可的要求,使帶狀態分配器不僅實用性得到提升,而且可管理進程外的共享記憶體。現今分配器的作用多為讓程式設計師可以控制容器的記憶體分配,而非適應基底硬體的地址模型。事實上,C++11標準刪去了分配器“自適應地址模型”的功能,結果抹消了其設計初衷。

熱門詞條

聯絡我們