多语言展示
当前在线:1984今日阅读:183今日分享:45

怎样提高共享内存频繁更新的效率?

已知key是定长二进制串(比如你说的MAC)时,应该充分利用这一性质,选用更优的数据结构,而不是像std::map这种只依赖key比较运算符的平衡树实现。
方法/步骤
1

两种方法,一种是一条全局的lockfreeQueue,然后有线程数条,比如BCDEF,只负责搜索并获取数据并将得到的数据push进Queue,同时有且只有一条线程A,专门从Queue里pop并建立map.同时,在你所说的'详细数据'的头部或者尾部,搞个Atomic的mark,一旦该MAC地址已经失效,并不是有发现其失效的线程从map中删除该MAC地址和详细信息,而是一个CAS操作直接将该地址对应的mark标记一下,然后依然由A来负责真正从map中删除被mark的信息. 这样的好处是,不但BCDEF之间不会阻塞,连A与他们之间也不会阻塞,唯一可能的坏处是唯一能够操作map的只有A,A要干的事情比BCDEF都多.

2

另一种方法就复杂了,首先需要一个固定长度数组,用MAC地址求余的方法构成一个Hashmap,不妨设为2^16长度,其中每个元素都是一个lockfree的队列,由于Hashmap中,你只访问某个下标对应的Queue,而不修改HashMap本身,所以Hashmap本身不存在lock的问题,然后这些应该是可以组成一个简易的lockfree的map了.然后你这些线程就随意玩不用加锁了....

3

当然,以上这些要实现,首先你得有个lockfree的队列....所以再说一个接地气的,未必比上面好,但是应该比你现在要快些,即,每个线程先格子持有一个数组,用来暂存mac地址和对应的信息,然后肯定要个统一map对吧,依然对它加锁,只不过任何线程访问它的时候,不要lock,要trylock,如果没try成功,就先把MAC地址存在自己的缓存里.一旦try成功,就一次性将所有的缓存中的东西全塞进map,并清空自己的缓存.同时,任何线程如果检测到某个MAC地址消失了,先从自己的缓存中查找是否有对应的MAC地址,如果有,则直接从自己的缓存里删掉.就不用去找那个全局的map了.

推荐信息