当前位置: 首页 > news >正文

对BSD的新路由查找算法的理解

bsd的路由查找算法我研究过一段时间,当时我们要自己写一个路由查找模块,要扩展性好的,要紧凑的,耦合性低的,于是我就选择了bsd的radix算 法,它不同于linux的哈希表查找算法,linux内核实现了两种查找算法,一个是哈希表算法,一个是LC-trie算法,我感觉linux设计的东西 不是那么紧凑,但绝对是一件艺术品,比较适合有品味的人欣赏和使用,大多数人还是驯服不了它,唉,承认自己的品味低,只好选择radix算法了,这里我绝 对没有贬低它的意思,其实我自己比较欣赏radix的,呵呵。bsd强调的东西和linux不同,在统一性方面不管是windows还是bsd做的都要比 linux好。闲话不扯了。 
基于radix树的查找算法中,bsd将一个ip地址分为解成了一个二进制比特串(计算机中它本身就是比特串,我是从读内核的人的角度分析的),然后在一颗二叉radix树中进行查找匹配,树的节点是需要测试的比特位,比如一个树节点的数据是15,那么当这个ip二进制串到达这里时就要测试第15位,如果 15为1,则向右拐,如果为0则向左拐,直到叶子节点,如果这个条目和需要的匹配则就是它了,如果不匹配,则回溯,不断的检查回溯过程中的掩码链表,以期 求得一个更大范围的普适路由。就是这样了,但是我们来看看会出现什么问题。 
首先,整棵树是那么的紧凑以至于我们必须将它作为一个整体,linux就好得多了,内核中的路由表以fib_table为顶向下分为了好多层,比如 fn_zone,fib_node,fib_alias,fib_info,fib_nh,这么几层下来每层都是独立的,可灵活维护的,这看起来非常灵活,不需要整个路由表的全局锁,只有在写操作时有一个fib_hash_lock,只要分开的东西就可能被并行计算看到,因此这样会比较好,所有 linux的优点恰恰是bsd的缺点,要访问路由表时要全局加锁,一下子锁住全树,就像linux以前访问文件页高速缓存全局锁一样,这样在现代的多处理器环境下非常不利,于是它变化了。 
新的bsd路由查找算法也是分层的,但是它的分层比linux更前进了一步,它不但将算法分层,还将ip地址分层,其实叫分级,把一个ip地址分为相等的 4份,每份8位,每8位每8位的进行匹配,这样只需要锁柱正在计算的8位就可以了,实际上,它将计算给分解了,这非常类似于虚拟地址到物理地址转化时的机 制,页目录负责高10位,页表负责中10位等等,而且恰恰巧的是,它就是这么实现的,本质上,它并没有改变原先的radix的实质,只不过将比较位数扩展 为了8位,以前的比较中,只比较1位非1即0,走形方向非左即右,现在比较8位,就不是非左即右了,而是成了n叉树,具体走哪一叉和原来一样,要看前一级的比较结果,这个算法实际上如果写得好的话,可以在原来的radix基础上扩充,我觉得这个新实现和linux内核的页高速缓存的radix树一样。 

经过这盘更改后效率当然提高了很多,每一级的计算要有8位参与,这个计算量恰好适合现代处理器的超标量以及超线程及多核进行并行处理,速度加快,而且一次 算8位,总的计算次数只有4次,不像以前的32次,每次1位还不够处理器塞牙缝呢,浪费了大量处理器,另外不再需要全局锁了,因为计算就不是全局的。更重 要的是,以前的一次比较1位根本无法利用cpu缓存,比较意味着处理器分支预测,你让处理器那么多次的猜你的心,它会疯的,而现在一次读入8个位,数据都 在缓存里面,随便用,当然比较还是也有分支预测失败,但是数据都在缓存,可以不必理会存储器,而以前的一次1位你根本不知道下面该取什么数据了,现在存储 器的带宽那么高全浪费了,就算你不让他浪费,结果该往左拐的预先取到右节点的数据,全错了,刷新缓存浪费更厉害。



 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1274168

相关文章:

  • 验证文件中记录总行数是否与数据库文件同名表记录总数是否一致
  • 编写一个Linux虚拟网卡来实现类NVI
  • Windows下powershell可执行python
  • Css基本样式————文本
  • js 简单实现 LRU
  • DoS Attacks Prevention with TCP Intercept
  • NIOS2随笔——自定义IP(DPRAM)
  • Webpack入门教程十五
  • IPv6, DAD 工作原理详解
  • 解决configure: error: Please reinstall the libcurl distribution
  • tweak 支持第三方库
  • 第十一章 持有对象
  • 条件变量的接口函数和使用原则
  • C# DataGridView中DataGridViewComboBoxCell列,下拉框事件的处理【完美解决】
  • C# 中的枚举类型 enum (属于值类型)
  • [译]CSS 居中(Center)方法大合集
  • 【Leetcode】104. 二叉树的最大深度
  • Bytom交易说明(账户管理模式)
  • CentOS 7 修改主机名
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • HTTP--网络协议分层,http历史(二)
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • leetcode-27. Remove Element
  • LeetCode算法系列_0891_子序列宽度之和
  • nodejs调试方法
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 前端设计模式
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 树莓派用上kodexplorer也能玩成私有网盘
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (day 12)JavaScript学习笔记(数组3)
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET开发者必备的11款免费工具
  • @Bean有哪些属性
  • @RequestMapping 的作用是什么?
  • @Transactional 详解
  • [ Algorithm ] N次方算法 N Square 动态规划解决
  • [ vulhub漏洞复现篇 ] JBOSS AS 4.x以下反序列化远程代码执行漏洞CVE-2017-7504
  • [ 云计算 | Azure 实践 ] 在 Azure 门户中创建 VM 虚拟机并进行验证
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [CC-FNCS]Chef and Churu
  • [CSS]CSS 字体属性
  • [HTML API]HTMLCollection
  • [HUBUCTF 2022 新生赛]