一种访问全局哈希表“避免”锁定的方法

时间:2013-09-05 04:33:03

标签: multithreading math lock-free

在我的项目中,有N个线程可以访问全局哈希表,这是不可避免的。所以我认为我应该使用无锁哈希表或其他东西。毕竟,我选择尝试别的东西,而不是lockfree哈希表,因为lockfree哈希通常用于特殊目的而且不是那么容易使用。

我的想法是:

N 个线程来访问全局哈希表,因此我将哈希表溢出到 M 子哈希表,其中 M > ; = N 。在任何时候,从M个子哈希表中选择N个子哈希表的所有线程的总和是pow(M,N),并且从M个子哈希表中选择N个子哈希表的总和是P(M, N),因此没有竞争条件的比率是P(M,N)/ pow(M,N),并且竞争条件的比率是 1-P(M,N)/ pow( M,N),即1-M!/(MN)!/ pow(M,N)。

我的计算, r 表示有竞争条件的比率:

线程数= 2

n=2, m=2 r=0.5
n=2, m=3 r=0.333333
n=2, m=4 r=0.25
n=2, m=5 r=0.2
n=2, m=6 r=0.166667
n=2, m=7 r=0.142857
n=2, m=8 r=0.125
n=2, m=9 r=0.111111
n=2, m=10 r=0.1
n=2, m=11 r=0.0909091
...
n=2, m=100 r=0.01
...

线程数= 3

n=3, m=3 r=0.777778
n=3, m=4 r=0.625
n=3, m=5 r=0.52
n=3, m=6 r=0.444444
n=3, m=7 r=0.387755
...
n=3, m=29 r=0.10107
...

线程数= 5

n=5, m=5 r=0.9616
n=5, m=6 r=0.907407
n=5, m=7 r=0.850062
n=5, m=8 r=0.794922
n=5, m=9 r=0.743941
...
n=5, m=96 r=0.100425

线程数= 8

n=8, m=8 r=0.997597
n=8, m=9 r=0.99157
n=8, m=10 r=0.981856
n=8, m=11 r=0.968964
n=8, m=12 r=0.953583
...
n=8, m=268 r=0.100095

优点是选择合适的m,我们可以在90%的时间内获得无锁

缺点是我们浪费了大量资源。

我的想法是对的吗?有没有更好的解决方案?

1 个答案:

答案 0 :(得分:0)

我认为算法的复杂性不值得它的好处。实际上有更简单的解决方案。在开始之前,最好确定使用模式。我可以这样总结一下:

  • HashTable readonly - 初始化一次,读取是安全的。
  • 仅附加或读/写比率高 - 每次写入时重新创建哈希表并使用Interlocked.CompareExchange替换。
  • 读/写比率低 - 使用基于spinwait的读/写器锁。

请记住 - 确定问题最佳解决方案的唯一方法是仔细测试和测量!