博文

ACK, SACK, D-SACK

In an ACK, the Acknowledgment Number field indicates the number for the next byte in the contiguous byte stream that the ACK’s sender expects to receive。

SACK(RFC 2018): SACK包含多个块,每个块里是已收到的。

通常来说  ACK < SLE1 < SRE1 < SLE2 < SRE2 ...

ACK是我下一个想要的,[SLE1, SRE1],[SLE2, SRE2]是我已经收到的。


D-SACK(rfc2883): 这种是SLE1<ACK的情形

例如:
Transmitted    Received    ACK Sent
Segment        Segment     (Including SACK Blocks)

3000-3499      3000-3499   3500 (ACK dropped)
3500-3999      3500-3999   4000 (ACK dropped)
3000-3499      3000-3499   4000, SACK=3000-3500

OS:Windows Server 2008 and Windows Vista, Linux 2.4+

Fast retransmit: 连续收到多个重复的ACK。

TODO: RFC 3517

想换个新路由器

我现在的路由器是netgear r6300v2,真的是太赞了。网上口碑甚好。这是我用的第一款基于ARM的路由器。但是我还是想换一个更好一点的。

于是在思索两种方案,一个是继续走ARM的路买一个r6300的升级版,另一个是选一个mini-itx无风扇的系统装Linux做软路由。

然后我先调查了一下ARM的情况。SoC基本被高通和Broadcom垄断了。

高通家的可以分为两类:IPQ4018/IPQ4019/IPQ4028。Cortex A7,主频717 MHz,比如Google Wifi,netgear Orbi就采用了这系列。
 另外就是IPQ8062/IPQ8064/IPQ8065等等。这些用的是Krait处理器,主频和A15差不多。 代表作Netgear R7800。

另外就是Broadcom Northstar系列:BCM4707/BCM4708/BCM4709/...,比如我的6300v2用的就是BCM4708A0。这些基本都是基于Cortex A9的。基于Cortex A53的设备我只找到两个:ASUS RT-AC86U,它用的是BCM4906,以及LINKSYS EA9300,基于Broadcom BCM4908。前者售价大约1000,后者2000。我还看不出来为什么后面这个这么贵。

目前看起来,ASUS RT-AC86U真是性价首选。但是netgear的设备对open source支持的更好些。

嗯,其实我未必需要wifi啊。哪怕给我一个纯路由,我在后面再接别的也行啊。不知道是不是选择可以更多一些。

再说x86这边。大部分低功耗的主板都只有一个网口,所以不适合做路由。高功耗的主板需要风扇,对我来说太吵了。我找来找去,非山寨的,就只有超微在做这样的产品。目前看中了E200-9B。E100-9AP和E200-9AP看着也不错但是我不知道去哪买。总之这些都很贵,至少2000元以上。但是优点是我可以用最新的Linux发行版和内核,可定制程度高,而且不用交叉编译不用移植代码省人工啊!就是我不知道噪音情况怎样。

web证书现在需要 Subject Alternative Name了

我刚发现我之前自己给自己签发的web server的证书在chrome下都失效。 chrome提示说:
 security certificate is from [missing_subjectAltName]. This may be caused by a misconfiguration or an attacker intercepting your connection.

据说这是chrome 58开始的新特性。我在找怎么修改openssl的命令以添加这个新属性进去。找了一半天没找到,网上的文档似乎都是得写一个配置文件才行,而我又比较懒。

我现在用的命令是:

openssl genrsa -out server.key 2048

openssl req -new -key server.key -out server.csr

openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt -extensions v3_req

如果你知道新的正确的,请告诉我




2017-07-03

上个月给手机升级了Android O,太慢太卡了,于是今天又刷回Android 7.1。顺便root了一下。我是通过自己编译adbd然后放入boot.img来root,但是很奇怪,似乎我用cpio手动打包的initrd.img 总是有问题,不能boot。只能通过在asop的源代码中make bootimg来生成boot.img才行。嗯……一定是我漏了什么。


tensorflow resource notes

在单机版中,创建session的时候会创建devices,创建device的时候会为每个device创建一个ResourceMgr。每个ResourceMgr可以有多个container。所以,在单机版中,session被销毁后它所对应的ResourceMgr里的那些resource也会被销毁。但是分布式版中就不是如此了。

ResourceMgr有这样一个成员:

std::unordered_map<string, Container*> containers_;

container name一般是job name。每个Container里面会放很多从ResourceBase继承来的resource。

  typedef std::pair<uint64, string> ResourceKey;
  typedef std::unordered_map<ResourceKey, ResourceBase*> Container;

单机版无GPU的情况下,默认的device name是"/job:localhost/replica:0/task:0/cpu:0"。其中,job name就是localhost。

单机版的TF会运行每个step的时候,在DirectSession::RunState的构造函数中创建一个per-step的container(ScopedStepContainer),用来存放per-step resources。

ResourceKey里的那个string是resource name,一般是node name。而那个uint64是那个ResourceBase的子类的type的hash_code(type_index.hash_code())。所以不同类型的Resource可以重名。所以,对于某个特定的session来说,它是通过(device name, resource type, container name, resource name) 这样的四元组来定位到一个resource。

DT_RESOURCE是一种新的tensor类型,大约是在去年10月份的时候,0.12版加入的。它所对应的数据类型是ResourceHandle protobuf。该对象的创建以及访问被封装在Res…

offline job resource management的问题

假设我有一些分布式的、离线的计算任务需要运行。我有100台机器。每个任务有固定的资源需求。比如任务A需要30台,2个小时。任务B需要40台,3个小时。这些任务类型是固定的,但是任务数量以及什么时候被提交上来是未知的。此时对于资源管理器(resource manager)来说,就有了资源利用率和调度公平性之间的权衡考虑。

举个例子。假设我现在只有35台空闲机器,此时任务B先被提交上来,它需要40台机器。我不能满足它。接着,任务A被提交上来,它只需要30台机器,我可以满足它。那么要让任务A先于任务B开始运行吗?如果不允许,那么就会浪费很多机器资源。这时候平台部门就会遭遇质疑:为什么整个cluster有1/3都是闲着,却有让大量的job在排队?
如果允许,那么就会造成小任务优先、大任务饿死。同样会遭人质疑。就像餐馆里如果某座来的早却菜上的晚,那么服务员就得做好挨骂的准备。

There is no perfect rules。但对于大多数公司来说,机器空闲率都是重要的考核指标,公平性这东西太过于抽象,没法考核。所以对于平台部门,一般都会为了提高机器使用率而牺牲公平性。我觉得这也是KPI机制的弊端之一。

如果你什么都不想,只是让Hadoop的yarn来调度资源,每个app自己去找yarn的resource manager来申请资源。那么,yarn其实不知道app把机器申请去了之后有没有实际在用,所以不会在机器使用率上达到一个优化的调度。对于APP来说,它本来只需要40台机器3个小时,但是为了等到这40台机器可能要等10个小时,而这10个小时它可能一直在占用大量的机器。

只要资源很紧张,再接下来,几乎一定会遇到job优先级的问题。有了优先级,一般就会做oversell 以及 可抢占式调度。这样才能让高优先级的任务真正“优先”起来。否则只能人为的划分多个cluster,从而又降低了机器使用率。



tensorflow中实现分布式的Barrier挺让人头疼

分布式training中,经常需要让所有的节点在某一个点同步一下。比如,

只有id=0的worker进行完所有初始化操作后,其它的worker才能开始运行training只有所有的worker都train完后,才能开始dump model 那么怎么实现这样的同步功能呢?最naive的做法是,声明一个int类型、形状为scalar 的 tensorflow variable。这个variable的初始值为0,每个worker到达sync point的时候,就把这个tensor的值加1。然后不停的sleep && get value。如下面代码所示: 声明
finished = tf.get_variable("worker_finished", [],tf.int32,tf.zeros_initializer(tf.int32),trainable=False) with finished.graph.colocate_with(finished): finish_op = finished.assign_add(1,use_locking=True) 使用:
worker_finished = sess.run(finish_op) print('%d worker finished' % worker_finished) if is_chief: try: while worker_finished < worker_count: time.sleep(3) worker_finished = raw_sess.run(finished) print('%d worker finished' % worker_finished) except Exception as ex: print('exit with error:%s' % str(ex)) return
但是这样有个缺点:所有的variable默认都会被写入到checkpoint中,这个也不例外。所以,当下次从checkpoint中再载入时,就乱套了。能不能不让saver保存这个variable? 可…