alloc_large_system_hash
【概念】-------------------------------------------------------------------------------------
哈希表
键 key
值 value
映射函数 Hash(key)
哈希函数(散列函数)
哈希函数应该易于计算,并且尽量使计算出来的索引值均匀分布。
哈希函数计算得到的哈希值是一个固定长度的输出值。
如果 Hash(key1) 不等于 Hash(key2),那么 key1、key2 一定不相等。
如果 Hash(key1) 等于 Hash(key2),那么 key1、key2 可能相等,也可能不相等(会发生哈希碰撞)。
方法:
直接定址法
取关键字本身 / 关键字的某个线性函数值 作为哈希地址。
即:Hash(key) = key 或者 Hash(key) = a * key + b,其中 a 和 b 为常数。
除留余数法
质数
除留余数法:假设哈希表的表长为 m,取一个不大于 m 但接近或等于 m 的质数 p,利用取模运算,
将关键字转换为哈希地址。即:Hash(key) = key % p,其中 p 为不大于 m 的质数。
平方取中法
平方取中法:先通过求关键字平方值的方式扩大相近数之间的差别,然后根据表长度取关键字平方值的中间几位数为哈希地址。
比如:Hash(key) = (key * key) // 100 % 1000,先计算平方,去除末尾的 2 位数,再取中间 3 位数作为哈希地址。
基数转换法
基数转换法:将关键字看成另一种进制的数再转换成原来进制的数,然后选其中几位作为哈希地址。
比如,将关键字看做是 13 进制的数,再将其转变为 10 进制的数,将其作为哈希地址。
以 343246 为例,哈希地址计算方式如下:
$343246{13} = 3 \times 13^5 + 4 \times 13^4 + 3 \times 13^3 + 2 \times 13^2 + 4 \times 13^1 + 6 \times 13^0 = 1235110{10}$
数字分析法
折叠法
随机数法
乘积法
点积法等
哈希冲突
哈希冲突(Hash Collision):不同的关键字通过同一个哈希函数可能得到同一哈希地址,
即 key1 ≠ key2,而 Hash(key1) = Hash(key2),这种现象称为哈希冲突。
开放地址法
当发生冲突时,开放地址法按照下面的方法求得后继哈希地址:H(i) = (Hash(key) + F(i)) % m,i = 1, 2, 3, ..., n (n ≤ m - 1)。
链地址法
链地址法(Chaining):将具有相同哈希地址的元素(或记录)存储在同一个线性链表中。
数组
哈希表(散列表)
Futex
概述: Futex(Fast Userspace Mutex)是linux的一种特有机制,
设计目标是避免传统的线程同步原语(如mutex、条件变量等)在用户空间和内核空间之间频繁的上下文切换。
Futex允许在用户空间处理锁定和等待的操作,只有在必要时进入内核,从而减少了不必要的开销。
【边界】-------------------------------------------------------------------------------------
futex
futex_wait()
futex_wake()
Futex原子操作:用户空间线程首先执行一些原子操作(如使用atomic函数或cmpxchg指令)来尝试获取锁
短路路径:如果锁在用户空间已经被释放,线程可以直接在用户空间完成同步,无需涉及内核
等待:如果一个线程尝试获取的锁已经被另一个线程占用,它可以调用futex_wait()进入休眠
唤醒:当锁被释放,另一个线程可以调用futex_wake()唤醒等待的线程
pthread_mutex:在linux中,pthread_mutex是基于futex实现的。
内存屏障和自旋锁:在一些高效的同步机制中,futex也常常与自旋锁、内存屏障等技术结合使用
【阶段】-------------------------------------------------------------------------------------
core_initcall(futex_init);
futex_init
alloc_large_system_hash
memblock_alloc(size, SMP_CACHE_BYTES);
参数依赖
size = bucketsize << log2qty;
log2qty = ilog2(numentries);
【信息】-------------------------------------------------------------------------------------
【问题】-------------------------------------------------------------------------------------
【对比】-------------------------------------------------------------------------------------
SpinLock:如果上锁成功,立即进入临界区,开销很小;但是如果上锁失败,CPU空转,浪费资源
Mutex:如果上锁失败,内核会切换到其他线程在CPU运行,不用自旋等待锁;但是即使是上锁成功也要进出内核,使用系统调用,会消耗几百个指令
Futex:结合上述二者的优点,在用户态尝试上锁,上锁成功既可以不用进入内核态,上锁失败就通过系统调用睡眠,唤醒也要通过系统调用
在用户空间尝试加锁通常通过原子操作来完成,如CAS(Compare-And-Swap)或者其他无锁的原子操作
2357

被折叠的 条评论
为什么被折叠?



