日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

学习 LLVM(14) SmallPtrSet

發布時間:2025/3/21 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学习 LLVM(14) SmallPtrSet 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

文件位于 llvm/include/llvm/[[ADT]]/SmallPtrSet.h

文件注釋:'Normally small' pointer set -- 一般小型指針集合。

== 定義的類 ==
* RoundUpToPowerOfTwo -- N 取整到 2 的冪次。
* RoundUpToPowerOfTwoH -- 輔助 N 取整到 2 的冪次。
* [[SmallPtrSetImpl]]
* [[SmallPtrSetIteratorImpl]]
* [[SmallPtrSetIterator]]
* [[SmallPtrSet]]

== 輔助模板 RoundUpToPowerOfTwoH ==
輔助模板 RoundUpToPowerOfTwoH<N, isPowerTwo> - 如果 N 不是 2 的冪次,則增加它。這個模板類用于輔助實現 [[RoundUpToPowerOfTwo]]。

類概要:
<syntaxhighlight lang="cpp">
template<unsigned N, bool isPowerTwo> struct RoundUpToPowerOfTwoH {
? enum { Val = N }; // 普通版本,class::Val == N
};

template<unsigned N> struct RoundUpToPowerOfTwoH<N, false> {
? // 特化版本,class::Val == N,是最小的大于 N 的 2 的冪次。
? enum {
??? // N|(N-1) 設置右邊的 0 比特位為 1,如 0b00101100 -> 0b00101111。
??? // We could just use NextVal = N+1, but this converges faster.? N|(N-1) sets
??? // the right-most zero bits to one all at once, e.g. 0b0011000 -> 0b0011111.
??? Val = RoundUpToPowerOfTwo<(N|(N-1)) + 1>::Val // 注意:配合 RoundUpToPowerOfTwo
? };
};
</syntaxhighlight>

如果 N 里面 1010 中間帶 0 比較多,可能要遞歸展開幾次 RoundUpToPowerOfTwo,能否有更好的辦法呢?

== 輔助模板類 RoundUpToPowerOfTwo ==
RoundUpToPowerOfTwo - 輔助模板類,用于求取最小的大于等于 N 的 2 的冪次。如果 N 已經是 2 的冪次,則值既是 N。

類概要:
<syntaxhighlight lang="cpp">
template<unsigned N>
struct RoundUpToPowerOfTwo {
? static bool isPowerTwo = (N&(N-1)) == 0}; // 判斷 N 是否已經是2的冪次。
? enum { Val = RoundUpToPowerOfTwoH<N, isPowerTwo>::Val }; // 取整到 2 的冪次。
}
</syntaxhighlight>

為了看起來易懂,我添加了 bool isPowerTwo,其中 N&(N-1) 是典型的判斷是否是 2 的冪次的方法。

== 類 SmallPtrSetImpl ==
類 SmallPtrSetImpl 提供給 SmallPtrSet<> 模板類作為公共基類。SmallPtrSet 有兩種模式,small 和 large 集合。類似于 [[SmallVector]], [[SmallString]] 等 Small 系列容器。

SmallPtrSet 里面有在對象內的指針數組,在 small 模式下,指針加入到這個數組中。如果這個數組不夠用了,則自動增長到 large 模式。因而,當集合通常比較小的時候,應該用 SmallSet,此時不進行額外的內存分配。

large 模式下使用典型的指數探測(exponentially-probed)哈希表。空桶以非法指針值(-1)表示,這樣允許插入 null 指針。墓碑(tombstone)以另一個非法指針值(-2)表示,以允許從集合中刪除。哈希表裝載因子達到 3/4(0.75) 的時候將自動擴充,表的大小加倍。

類概要:
<syntaxhighlight lang="cpp">
class SmallPtrSetImpl {
? PTR SmallArray[]; // 保存指針類型PTR 的數組,small 模式下用。
? PTR CurArray[];?? // 當前使用的指針數組,如果 == SmallArray,則表示在 small 模式下。?
? unsigned CurArraySize; // CurArray 的大小,取值是 2 的冪次。
? unsigned NumElements;? // 已在集合中的元素數量。
? unsigned NumTombstones;// 被刪除的元素數量。
?
? this(), ~this() // 帶參數的構造、析構。protected 只能被派生類使用。
? empty(),size(),clear()? 容器方法
? emptyMarker -- (void*)-1? 使用 -1 作為空槽標記。
? tombstoneMarker -- (void*)-2?? 使用 -2 作為墓碑(被刪除元素)標記。
? hash(), grow(), find(), ... // 很多給派生類使用的實現輔助函數
}
</syntaxhighlight>

類中各個數據、函數的使用放在派生類 SmallPtrSet 中說明。

== 類 SmallPtrSetIteratorImpl ==
SmallPtrSetIteratorImpl - 作為模板 SmallPtrSetIterator<> 的公共基類。

類概要如下:
<syntaxhighlight lang="cpp">
class SmallPtrSetIteratorImpl {
? void **Bucket;? // 指向 hashtable 桶的指針。為清晰,去掉了 const 修飾符。
? this(), ==, !=, ++ 的實現,由派生類使用。
}
</syntaxhighlight>

== 類 SmallPtrSetIterator ==
為 SmallPtrSet 實現 const_iterator,類概要如下:
<syntaxhighlight lang="cpp">
template<typename PtrTy> class SmallPtrSetIterator
? : public SmallPtrSetIteratorImpl { // 派生自...
? value_type, reference, pointer 等標準容器類型定義
?
? this(), *, ++? 迭代器的實現。這是一個僅向前迭代器(forward_iterator_tag)。
}
</syntaxhighlight>

== 類 SmallPtrSet ==
模板類 SmallPtrSet 實現為存儲少量元素而進行優化的集合。內部將對 SmallSize 參數取整到 2 的冪次。

類概要:
<syntaxhighlight lang="cpp">
template<class PtrType, unsigned SmallSize>? // 參數:指針類型,元素數量
class SmallPtrSet : public SmallPtrSetImpl {
? enum SmallSizePowTwo // 對 SmallSize 取整到 2 的冪次。用 RoundUpToPowerOfTwo 實現
? void *SmallStorage[SmallSizePowTwo+1];? // in-object 指針存儲。
?
? this()? // 普通構造與復制構造,等等。
? begin(),end(),insert(),erase(),count() 等標準容器方法實現。
? ... 其它略
}
</syntaxhighlight>

== SmallSetPtr 實現機理 ==
SmallSetPtr 的幾個主要函數實際都實現在 SmallSetPtrImpl 中,也即在 SmallSetPtr.cpp 文件中實現。主要學習 insert, erase, find 等核心的方法。

=== insert() ===
insert(ptr) -- 用于向集合中插入新元素 ptr

前述提到有兩種模式,small 和 large。插入的過程如下:
* 1. 判斷是否 small 模式?依據是 CurArray 指向的是內部 in-object 的那個 SmallStorage 數組。
* 2. 在 small 模式下,線性掃描 SmallStorage[] 以查找 ptr 是否已經存在。如果存在則返回 false 表示插入失敗(或不需要插入)
* 3. 如果沒找到,并且 SmallStorage[] 還有空間,則放到 SmallStorage[] 末尾,返回 true。
* 4. SmallStorage[] 沒有空間了,轉到 large 模式。
* 5. large 模式,判斷裝載因子(load factor) > 3/4 嗎?如果是,則 grow() 見注1.
* 6. 如果墓碑過多(空位置少于1/8),則 rehash。注2.
* 7. 為 ptr find_bucket(),如果找到的位置上已經是 ptr 了表示前面插入過了,則返回 false.
* 8. 否之該位置可以插入,在該位置插入,更新數據并返回 true。

關于為何使用 empty, tombstone 參見后面 erase(), find_bucket() 的說明。

* 注1:grow() SmallPtrSet 使用的是使用[[開放尋址法]]實現的 hash 表,因此不能有太大的裝載因子,否則導致性能急劇下降。3/4(0.75) 是一個較好的時間-空間平衡的裝載因子。
* 注2:rehash -- 刪除的元素被標記為墓碑(tombstone),如果墓碑過多將影響搜索效率,甚至導致無限循環搜索空位置。因此當墓碑標記過多的時候,需要重新 hash() 現有元素填放到正確的位置以消除墓碑。如果 grow() 增加了新空間,則會自動進行 hash() 同時消除了墓碑,因此那種情況不需要 rehash()。

=== erase() ===
erase(ptr) 用于從集合中刪除指定元素。

過程如下:
* 1. 如果是 small 模式,線性查找 SmallStorage[]。找到則刪除,返回true;沒找到則返回 false。
* 2. 為 ptr find_bucket()。如果沒找到,則返回 false.
* 3. 找到了,則標記這個 bucket 位置為墓碑(tombstone)表示元素被刪除了,返回 true。

=== find_bucket() ===
find_bucket(ptr) 為 ptr 查找所在桶的位置,如果沒有則返回可插入的空桶的位置。

find_bucket() 僅查找 large 模式下的 CurArray,這是一個開放尋址法實現的 hash 表。
* 1. 計算 ptr 的 hash 值。這里算法使用 hash & (桶數量-1)。因為桶數量(CurArraySize) 被要求是 2 的冪次,因此可以使用 & 操作。
* 2. 循環:
* 3.? 如果在 hash 的桶的就是 ptr 則找到了,返回這個桶位置。
* 4.? 如果 hash 的桶是 empty,表示找到一個空位置,沒有可能有重復的 ptr 在集合中,返回一個可用的桶位置。所謂可用,指要么用這個 empty 桶位置,要么前面有發現一個被刪除的元素位置(tombstone),則返回被刪除位置的桶。
* 5.? 如果 hash 的桶標記為 tombstone,則表示找到一個被刪除元素的位置。和 ptr 元素沖突的可能元素依舊可能存在,需要繼續查找,但記錄下這個 tombstone 的位置,其可能在步驟 4 返回。
* 6. hash 值加上 probe_amt++,繼續探測。按照這里的算法,應該是[[二次探測再散列]]。

墓碑(tombstone)用來標記被刪除的元素,如果沒有這種 tombstone 標記,幾個沖突的元素如果插入集合中,而前面的被刪除,則后面的就將探測不到了。

后面要學習的 DensyMap 也是用的二次探測法實現的。

轉載于:https://my.oschina.net/u/232554/blog/42364

總結

以上是生活随笔為你收集整理的学习 LLVM(14) SmallPtrSet的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产色综合天天综合网 | 色综合天天综合网天天狠天天 | 日本一区二区三区在线看 | 成人福利视频 | 丰满岳乱妇一区二区三区 | 日本大胆欧美人术艺术 | 五十路av在线| av青青草原 | 久久视频在线播放 | 国产大奶在线观看 | 在线观看涩涩 | 亚洲AV成人无码一二三区在线 | 久久久久久久久97 | av老司机久久 | 五月婷久久 | 成人小视频在线播放 | 蜜桃av鲁一鲁一鲁一鲁俄罗斯的 | 香蕉小视频 | 欧美成年人在线视频 | 中文字幕在线播放一区 | 久久久久国产一区 | 奇米成人影视 | 亚洲精品影视 | 日本四级电影 | 97人妻人人澡人人爽人人精品 | 欧美精品乱人伦久久久久久 | 99人妻碰碰碰久久久久禁片 | 国产又爽又黄的视频 | 国产精品日日摸天天碰 | 日本毛片在线 | 日韩成人av在线播放 | 91精品国产入口 | 白洁av| 伊人亚洲 | 第五色婷婷 | 日韩特级黄色片 | 在线看亚洲 | 免费av网站在线播放 | 性生交大片免费看女人按摩 | 六月婷婷激情网 | 24小时日本在线www免费的 | 欧美精品一区二区三区四区五区 | 先锋影音一区二区三区 | 夜夜骚av一区二区三区 | 天天视频天天爽 | 亚洲精品91在线 | 久久精品aⅴ无码中文字字幕重口 | aise爱色av| 亚洲欧美乱综合图片区小说区 | 在线播放网址 | 中文字幕一区二区在线播放 | av一区二| av电影在线网站 | 香蕉网在线视频 | 麻豆精品免费视频 | 亚洲国产日韩一区无码精品久久久 | 日韩av图片 | av手机观看| 亚洲福利电影 | 午夜影院网站 | 亚洲AV无码国产精品 | 樱花电影最新免费观看国语版 | 五月的婷婷 | va婷婷在线免费观看 | 国产亚洲91| 成人在线视频一区二区三区 | 国产亚洲AV无码成人网站在线 | 国内久久精品 | 9.1成人看片免费版 日韩经典在线 | 黄色片一区二区三区 | 调教丰满的已婚少妇在线观看 | 91在线公开视频 | 亚洲AV蜜桃永久无码精品性色 | 色黄大色黄女片免费中国 | 麻豆国产视频 | 免费黄色国产视频 | 精品免费在线 | 免费啪| 影音先锋中文字幕人妻 | 亚洲成人77777| 亚洲第一黄色片 | 人人干人人插 | 操欧美老女人 | 国产污污在线观看 | 久久思 | 91黄色小视频| 久久中文一区 | 国产激情av一区二区三区 | 久久神马影院 | 一区视频网站 | 色综合久久久久久久 | 天堂av中文字幕 | 精品国偷自产一区二区三区 | 在线欧美一区 | 婷婷.com| 久色亚洲 | 成人黄色片免费看 | 黄色小视频在线观看 | 中文字幕91 |