网络时钟同步协议-- NTP, PTP

这篇文章介绍一下两个时钟同步的网络协议:NTP和PTP。
这里不涉及协议的原理和具体实现(想了解的可自行Google),重点是如何搭建起这两个服务。

1. NTP及PTP简介


NTP(Network Time Protocol)是用于不同计算机之间同步时钟的网络协议。
它的设计目标是使所有的互连的机器之间的时钟与UTC时间只相差若干毫秒

目前NTP协议已经是有第4版了,如果不需要了解NTP太多细节的话,看看这个wiki页面应该就足够了。需要注意的就是它有clock strata的概念。

PTP(Precision Time Protocol)看名字就知道是一个比NTP更精确的时钟同步协议了,PTP的设计目标是使机器之间的时钟偏差在sub-microsecond范围—这是wiki页面上提到的,有其他的地方说的是偏差若干微秒,本文搭建的环境中测量到的偏差也在微秒级别,没有到sub-microsecond级别。在使用PTP协议时,需要了解的主要概念点就是它的master/slave机制。

接下来我们就介绍我搭建NTP和PTP环境的过程,所用到的操作系统是CentOS6.5,内核版本是3.10。其他软件的版本会在用到时提及。

2. 搭建NTP服务


配置环境:两台服务器,一台做NTP服务器,一台做NTP的客户端。同时这两台机器都未联网。
NTP服务器地址:192.168.0.11
NTP客户端地址:192.168.0.22

A. 在192.168.0.11中启动NTP服务

B. 在192.168.0.22上启动NTP服务,选择192.168.0.11为NTP服务器

我的这两台实验机器是在同一个Rack的,结果显示差不多同步的偏差在30ms左右。
每个版本的ntpd配置文件可能有少许的差别,不过好在注释都做的不错,所以别的细节就不啰嗦了。

3. 搭建PTP服务


List of PTP implementations可以看到PTP的实现有很多很多种,可以是硬件实现的,可以是软件实现的也可以是软硬件结合实现的。本文中搭建的PTP服务是基于软件PTPd。如果没有特殊的硬件的话,这算是一种非常方便的方法了。

如果遇到任何问题,首先一定要看看help,使用-H选项的话还能看到非常详细的配置(虽然大多我可看不懂,不过不能不看,理解的越多,遇到的问题就会越少)。
如果log里面的信息看不懂,可以把代码下下来,一个grep搞定。

经测试,在我的机器上使用PTPD软件搭建的服务,时钟偏移的平均值能够达到5us左右。这个粒度基本能满足我们的需求了。

参考链接


Linux中的时钟准确度

本文来自戴尔软件开发高级工程师Stuart Hayes

一个关于计时的问题最近引起了我的关注。 有用户在 Dell 服务器上运行 Linux,并且发现时钟时间(Linux 所报告的)每天误差五秒以上,偏差比较明显。

我们首先想到的也许是运行 NTP,定期与真实世界同步操作系统的时钟。

但是这样的误差最初是如何产生的?

在Linux运行时,Linux 系统未使用实时时钟(real time clock - RTC) 硬件来计时。 Linux 通常在启动时从RTC 读取时间,然后从该点开始,Linux 使用另一个时钟来源(系统中的另一个计时器/计数器)来计时。

自第 2.6.18 版起,Linux 的内核就使用 CPU 时间戳计数器 (TSC) 作为首选的时钟来源(假设 TSC 以恒定频率运行,以新款的 Intel 服务器 CPU为例)。 但是,尽管读取速度很快且解析度很高,TSC 却不是一个已知的频率。 当内核使启动时,它需要使用频率已知的另一个计时器,对其进行校准。 这样的校准并非天衣无缝(即使用于校准的计时器也是如此),因此把 TSC 作为时钟来源会造成时间误差。

如果减少时间误差对您非常重要,而非若干微秒的调度延迟,则最好使用频率已知的计时器,如大多数 x86 服务器上提供的 HPET(高精度事件计时器)。 借助新内核上的参数"clocksource=hpet"可实现这一目标。 HPET 计时器以已知、固定的频率运行,Linux 内核可直接从计时器读取时间。

话说回来,尽管 HPET 的精度高于 TSC,运行 NTP 以在 Linux 中实现长期的时钟精度始终是很好的想法。
上述讨论仅适用于运行于裸机的 Linux。 在虚拟机中的问题略微复杂。

原文链接


Linux 中的时钟准确度

Linux时钟精度:毫秒?微妙?纳秒?

最近被内核时钟精度弄的很是郁闷。具体情况如下:

扫盲:1秒=1000毫秒=1000000微妙=1000000000纳秒

首先:linux有一个很重要的概念——节拍,它的单位是(次/秒)。2.6内核这个值是1000,系统中用一个HZ的宏表征这个值。同时有全局的jiffies变量,表征从开机以来经过的节拍次数(这里面还有故事,后面说,先记住这个)。当然还有wall_jiffies的墙上jiffies来表示从 07-01-1970 到现在的节拍数。每个节拍里面执行一次时钟中断。就是说,它的精度是毫秒。

接着:内核中还有一个变量xtime表征系统的实际时间(墙上时间),定义如下。其中xtime.tv_sec以秒为单位,存放从Unix祖宗定的纪元时间(19700701)到现在的秒数。xtime.tv_nsec以纳秒为单位,记录从上一秒开始经过的纳秒数。就是说,它的精度是纳秒。


最后:linux提供一个gettimeofday的系统调用,它会返回一个timeval的结构体,定义如下。解释同上,tv_sec代表墙上时间的秒,tv_usec表示从上一秒到现在经过的微秒数。就是说,它的精度是微妙。

精彩的来了:
1. 内核中的xtime会在每个时钟中断的时候被更新一次,也就是每个节拍更新一次。你妹!!每毫秒更新一次怎么能冒出来纳秒的精度??而且,内核还有可能丢失节拍。怎么能是纳秒??
2. 各种书上说,gettimeofday系统调用是读取的xtime的值。日,为啥读出来之后精度丢了?变成微妙了?

寻寻觅觅终于理清了故事:
针对问题1:在linux启动的时候,一个节拍的时间长度还会以纳秒为单位初始化到tick_nsec中,初始化值为999848ns,坑爹啊!不到一毫秒!节拍大约为1000.15Hz。靠!实际的节拍竟然不是准确的1000!所以在每个时钟中断通过wall_jiffies去更新xtime的时候得到的就是一个以纳秒为最小单位的的值。所以!xtime的粒度应该是不到1毫秒,也就是精度是不到1毫秒。

针对问题2:gettimeday系统调用的读xtime代码部分如下:

while部分使用了seg锁,只看中间的就好了。加了注释之后就很清晰了。由于节拍可能会丢失,所以lost是丢失的节拍数(不会很多)。至于计时器就比较麻烦了,timer可能有下面四种情况。

a. 如果cur_timer指向timer_hpet对象,该方法使用HPET定时器——Inter与Microsoft开发的高精度定时器频率至少10MHz,也就是说此时可提供真正的微妙级精度。
b. 如果cur_timer指向timer_pmtmr对象,该方法使用ACPI PMT计时器(电源管理定时器)平率大约3.58MHz,也就是说也可以提供真正的微妙级精度。
c. 如果cur_timer指向timer_tsc对象,该方法使用时间戳计数器,内置在所有8086处理器,每个CPU时钟,计数器增加一次,频率就是CPU频率,所以timer精度最高。完全可以胜任微妙级的精度。
d. 如果cur_timer指向timer_pit对象,该方法使用PIT计数器,也即是最开始提到的节拍计数,频率大概是1000Hz,此时显然不能提供精度达到微妙的时间。所以只有这种情况是假毫秒精度!

综上:如果使用gettimeofday系统调用,只要不要使用节拍计数器就可以保证达到微妙精度的时间(刨除进程上下文时间误差)。至于网上说的可以拿到纳秒精度的时间,看起来都是错的。除非通过修改内核,使用时间戳计数器实现。Over!

最后最后说一个事情:jiffies的定义的是4字节,你可能猜想它初始值是0。实际上,事实并非如此!linux中jiffies被初始化为0xfffb6c20,它是一个32位有符号数,正好等于-300 000。因此,计数器会在系统启动5分钟内溢出。这是为了使对jiffies溢出处理有缺陷的内核代码在开发阶段被发现,避免此类问题出现在稳定版本中。

参考《深入理解linux内核》

原文链接


Linux时钟精度:毫秒?微妙?纳秒?

更优雅的(不拆硬盘)拯救死翘翘了的WD MyCloud(Ubuntu 17.10)

以前WD MyCloud被捣鼓坏掉了,都是参考拯救死翘翘了的 WD MyCloud来处理的,但是这种处理方式需要拆机,非常的费力。最近看到有人发布了可以不拆机的方式修复的方法。研究了一下,非常可行,推荐使用这种方法。

下面的这些操作都是WD论坛上的一些达人通过分析WD MyCloud的源代码得到的,没有非公开的黑科技,都是一些明确公布的内容。

原理大致讲一下,在WD MyCloud主板上有一块Flash闪存,闪存里面是已经写入的bareboxWD MyCloud启动的时候会把barebox从闪存载入到内存中,并且启动barebox,而barebox启动后,会等待5S的时间,检测是否有人向自己的网卡发送内容为WD-ICMP-BEACONWD-ICMP-BEACONWD-ICMP-BEACONWD-ICMP-ICMP报文(本质就是PING),一旦检测到这个报文,就会连接这个报文的发送方的69号端口(TFTP服务器端口),获取一个名为startup.sh的脚本,并且下载完成后,执行这个脚本。因此我们就可以在这个脚本中拉取一个自己编译好的内核,然后运行这个内核,达到修改系统的目的。

继续阅读更优雅的(不拆硬盘)拯救死翘翘了的WD MyCloud(Ubuntu 17.10)

ubuntu 17.10 gnome 3桌面隐藏顶栏

1.安装gnome-tweak-tool

2.安装hidetopbar扩展

3.重启电脑

4.启动gnome-tweak-tool

可以看到扩展-->Hide top bar扩展,开启即可隐藏顶栏。按键盘上的Windows图标键就会显示出来。如果还是没有隐藏,请点击设置按钮,在里面关闭智能隐藏

继续阅读ubuntu 17.10 gnome 3桌面隐藏顶栏

CNN 模型压缩与加速算法综述

CNN 模型压缩与加速算法综述

姜媚 2017-08-21 5760标签: CNN , 神经网络

导语:卷积神经网络日益增长的深度和尺寸为深度学习在移动端的部署带来了巨大的挑战,CNN模型压缩与加速成为了学术界和工业界都重点关注的研究领域之一。

前言

自从AlexNet一举夺得ILSVRC 2012 ImageNet图像分类竞赛的冠军后,卷积神经网络(CNN)的热潮便席卷了整个计算机视觉领域。CNN模型火速替代了传统人工设计(hand-crafted)特征和分类器,不仅提供了一种端到端的处理方法,还大幅度地刷新了各个图像竞赛任务的精度,更甚者超越了人眼的精度(LFW人脸识别任务)。CNN模型在不断逼近计算机视觉任务的精度极限的同时,其深度和尺寸也在成倍增长。

表1 几种经典模型的尺寸,计算量和参数数量对比

Model Model Size(MB) Million
Mult-Adds
Million
Parameters
AlexNet[1] >200 720 60
VGG16[2] >500 15300 138
GoogleNet[3] ~50 1550 6.8
Inception-v3[4] 90-100 5000 23.2

随之而来的是一个很尴尬的场景:如此巨大的模型只能在有限的平台下使用,根本无法移植到移动端和嵌入式芯片当中。就算想通过网络传输,但较高的带宽占用也让很多用户望而生畏。另一方面,大尺寸的模型也对设备功耗和运行速度带来了巨大的挑战。因此这样的模型距离实用还有一段距离。

在这样的情形下,模型小型化与加速成了亟待解决的问题。其实早期就有学者提出了一系列CNN模型压缩方法,包括权值剪值(prunning)和矩阵SVD分解等,但压缩率和效率还远不能令人满意。

近年来,关于模型小型化的算法从压缩角度上可以大致分为两类:从模型权重数值角度压缩和从网络架构角度压缩。另一方面,从兼顾计算速度方面,又可以划分为:仅压缩尺寸和压缩尺寸的同时提升速度。

本文主要讨论如下几篇代表性的文章和方法,包括SqueezeNet[5]、Deep Compression[6]、XNorNet[7]、Distilling[8]、MobileNet[9]和ShuffleNet[10],也可按照上述方法进行大致分类:

表2 几种经典压缩方法及对比

Method Compression Approach Speed Consideration
SqueezeNet architecture No
Deep Compression weights No
XNorNet weights Yes
Distilling architecture No
MobileNet architecture Yes
ShuffleNet architecture Yes

继续阅读CNN 模型压缩与加速算法综述

WD MyCloud拆硬盘恢复系统后容量部分显示0KB

捣鼓挂掉WD MyCloud之后,在参照 拯救死翘翘了的 WD My Cloud 恢复系统后,首页中的容量部分显示0KB,如下图:

解决方法为,进行一次"仅系统"的"系统出厂还原",如下图:

参考链接


MyCloud showing 0kb available, data and files cannot be accessed

让WordPress 4.9支持上传更多文件类型

WordPress对上传的文件类型是有限制的,在这里,我们以在子主题twentyfifteen-child中增加扩展名为.bz2的文件类型为例子。

首先编辑子主题的functions.php文件

在文件尾部增加如下内容:

参考链接


Ubuntu 16.04下用Python显示YUV格式的图片

YUV420p to RGB & view

UYVY/YUV422 to RGB and view:

原始链接


YUV to RGB : Python Imaging Library

Ubuntu14.04安装和配置ROS Indigo

安装ROS

配置Ubuntu的软件源

配置Ubuntu要求允许接受restricted、universe和multiverse的软件源,可以根据下面的链接配置:
https://help.ubuntu.com/community/Repositories/Ubuntu

配置成如下图所示即可,一般情况下,这些配置都是默认的。

添加软件源到sources.list

设置软件源的代码如下:

一旦添加了正确的软件源,操作系统就知道去哪里下载程序,并根据命令自动安装软件。

设置密钥

安装

首先确认你的Debian的软件包索引是最新的。Debian计划是一个致力于创建一个自由操作系统的合作组织。我们所创建的这个操作系统名为 Debian。Debian系统目前采用Linux内核或者FreeBSD内核。

在ROS中有许多不同的函数库和工具,建议是完全安装,也可以根据自己的要求分别安装。完全安装时的工具包括ROS、rqt、可视化环境rviz、通用机器人库robot-generic libraries、2D(如stage)和3D(如Gazebo)仿真环境2D/3D simulators、导航功能包集navigation and 2D/3D(移动、定位、地图绘制、机械臂控制)、感知库perception(如视觉、激光雷达、RGB-D摄像头等)。

初始化rosdep

rosdep不仅能够使你更方便的安装一些系统依赖程序包,而且ROS的一些主要部件的运行也需要rosdep。

安装rosinstall

rosinstall命令是一个使用的非常频繁的命令,使用这个命令可以轻松的下载许多ROS软件包。

设置环境

添加ROS的环境变量,这样,当你打开你新的shell时,你的bash会话中会自动添加环境变量。

配置你的ROS环境

注意:当你用像apt这样的软件包安装管理器安装ROS,那么这些软件包用户是没有权利的去编辑的,当创建一个ROS package和处理一个ROS package时,你应该始终选择一个你有权限工作的目录作为工作目录。

管理你的环境

在安装ROS的时候,你会看到提示:source(命令)几个setup.*sh文件,或者甚至添加sourcing到你的shell启动脚本中。这是必须的,因为ROS依赖于结合使用shell环境的概念上。这使得开发依赖不同版本的ROS或者不同系列的package更加容易。

如果你在寻找或者使用你的ROS package上有问题,请确定的你的ROS环境变量设置好了,检查是否有ROS_ROOT和ROS_PACKAGE_PATH这些环境变量。

如果没有,你需要source一些setup.*sh文件。

环境设置文件是为你产生的,但是可以来自不同的地方:

  • 使用package管理器安装的ROS package提供setup.*sh文件;
  • rosbuild workspace使用像rosws这样的工具提供setup.*sh文件;
  • setup.*sh文件在编译和安装catkin package时作为副产品创建。

注意:rosbuild和catkin是两种组织和编译ROS代码的方式,前者简单易用,后者更加复杂但是提供更多灵活性尤其是对那些需要去集成外部代码或者想发布自己软件的人。

如果你在Ubuntu 14.04上使用apt工具安装ROS,那么你会在'/opt/ros/indigo/'目录中有setup.*sh文件,你可以这样source它们:

你每次打开新的shell都需要运行这个命令,如果你把source /opt/ros/indigo/setup.bash添加进.bashrc文件就不必要每次打开一个新的shell都运行这条命令才能使用ROS的命令了。

创建ROS工作环境

对于ROS Groovy和之后的版本可以参考以下方式建立catkin工作环境。在shell中运行:

可以看到在src文件夹中可以看到一个CMakeLists.txt的链接文件,即使这个工作空间是空的(在src中没有package),任然可以建立一个工作空间。

catkin_make命令可以非常方便的建立一个catkin工作空间,在你的当前目录中可以看到有build和devel两个文件夹,在devel文件夹中可以看到许多个setup.*sh文件。启用这些文件都会覆盖你现在的环境变量,想了解更多,可以查看文档catkin。在继续下一步之前先启动你的新的setup.*sh 文件。

为了确认你的环境变量是否被setup脚本覆盖了,可以运行一下命令确认你的当前目录是否在环境变量中:

输出:

至此,你的环境已经建立好了,可以继续学习ROS文件系统了!

参考链接


Ubuntu14.04安装和配置ROS Indigo