Galaxy's World 银河雪尘

2022

June

2017

December

November

October

September

August

May

2016

April

March

February

January

2015

December

November

September

August

July

May

April

2014

August

June

May

April

March

February

January

2013

December

October

September

August

July

June

May

April

March

2012

December

November

July

June

May

April

March

2011

March


日本「我的朋友很少」的原因

http://www.hacg.me/wordpress/4988

关于CSS解决高度自适应和宽度自适应的问题

今天在做一个地图的web应用,这是个大坑…首先开始设计首页,于是开始山寨谷歌地图了 =.= 设计出来基本的div框架之后,想做到地图界面宽度和高度自动适应浏览器.之前做网站 的需求都是固定宽度和高度的.于是我变开始折腾了.

Latency Numbers Every Programmer Should Know

本文的灌水动机来自于5天前HN十大的一篇Latency Numbers Every Programmer Should Know, 一名UCB的学生将计算机系统中的延迟时间(latency time)进行了数据图形化猛击这里. 通过拖动标记年份的滚动条, 我们可以很直观地看到CPU cache, main memory, network上的科技进步对系统延迟时间的影响. 然而看完这幅图, 我不禁有点好奇这些数字的来源, 所以我对其进行了一下小调查.

虽然说是调查, 但如果有人细心观察过页面源代码的话, 其实就能发现作者已经在注释里做了很详细的引用说明了, 所以这篇大抵只是对注释的整理罢了XDDD


总的来说, 作者用到的数据大部分来自Peter Norvig的Teach Yourself Programming in Ten Years和Jeff Dean的Building Software Systems at Google and Lessons Learned, 也算是rule of thumb了. 同时, 描述硬件的进步趋势时, 大家都爱用”X年翻一倍”这种描述, 所以计算时也是用了简单的指数函数 \(y = a * b ^ x\).


首先是CPU主频的变化: 在2005之前, CPU的主频每两年就会翻倍(source, 38页; 其实摩尔定律更流行的说法是”每一美元所能买到的电脑性能,将每隔18个月翻两倍以上”, 这也是slides里面用的时间单位, 不过摩尔本人否认自己有这样说过, 而他的论文上确实写的是每两年一翻); 但是到了2005年, CPU的主频就停止在了3GHz(source).

既然主频已经无法再提高了, 芯片设计师开始把注意力放在了别的方面. 这里也涉及到摩尔定律好玩的地方. 摩尔定律的原话其实是: “半导体芯片上集成的晶体管和电阻数量将每两年增加一倍”. 因为CPU主频已经达到极限了,所以芯片设计师就开始利用剩下来的”晶体管预算”来改进CPU的其他方面, 例如往CPU塞更多的核. 而其实2005年也是第一个桌面双核CPU出现的年份: Athlon 64 X2.


当知道CPU的主频后, 就可以大致估算cache上的延迟时间了. 作者选用了PowerPC™ MPC7451来进行估算(source):

  • L1访问大概需要3个时钟周期
  • 分支预测错误的话会用掉10个时钟周期
  • L2访问需要13个时钟周期
  • Mutex锁/解锁需要50个时钟周期

相比起CPU的进步速度, 总线等待时间上的改善进度一直都算是很糟糕(source)…15年前(1998年)的数据是: 内存等待时间以每年7%的速度下降, 内存带宽以20%的速度增长(source).

作者将内存访问的延迟时间从2000年后就定在了100ns. 虽然作者没有明确说明, 不过100ns这个数字最早应该是来自Peter Norvig的Teach Yourself Programming in Ten Years, 而之后也被Jeff Dean沿用下来了, 如Building Software Systems at Google and Lessons Learned, 所以这个数字就当做rule of thumb好了.


周边的带宽增长趋势的数据大部分来自Warehouse-Scale Computing and the BDAS Stack.

  • 网卡(Network Interface Controller, NIC)带宽是每两年翻一倍, 作者认为在2003年是网卡带宽达到了1Gb/s
  • DRAM带宽每三年翻一倍, 在2001年从内存读1MB需要用250,000 ns
  • SSD带宽每三年翻一倍, 在2012年时达到3GB/s
  • 硬盘的带宽增长速度颇为杯具…在2002年时大概每两年翻一倍, 之后需要五年才翻一倍; 在2002年时带宽约为100MB/s

剩下的部分:

  • 关于硬盘, 寻找+旋转的等待时间每十年减少一半(source), 在2000年时这数字大约是10ms
  • 至于SDD, 在2012年之前, 三个翻倍周期(doubling cycle, 即18个月)可以使访问等待时间降低20倍(source), 而在2012年是该数字是20us. 而之后的进步空间看似也不大了
  • 数据中心的RTT(Round-Trip Time)估计是500000ns, 估计也不会有太大改变了
  • 根据Moving Beyond End-to-End Path Information to Optimize CDN Performance, 路由似乎还有提升的空间. Wan RTT现在估计是150000000ns.

Reference


History


  • 12:17 AM Sunday, December 31, 2012 First commit

Typechecking tricks using macros in C

短笔记一篇嗯…

事发于豆瓣上的学习型友邻A Liutos君在前晚提出一个话题”要是C的宏对参数也有类型要求就好了”, 然后学习型友邻B Fleuria叔果断告知了”Linux内核里的宏许多都加有类型检查的tricks”. 然后菜逼小弟就在跟帖里学习涨姿势了= =….

在Linux内核的kernel.h里的min(x, y)就用到了类型检查的tricks:

#define min(x, y) ({                                \
        	typeof(x) _min1 = (x);                  \
        	typeof(y) _min2 = (y);                  \
        	(void) (&_min1 == &_min2);              \
        	_min1 < _min2 ? _min1 : _min2; })

需要注意的的地方是:

  • typeof 是gcc extensions的特性,并不属于c标准. 这不禁让我很好奇如果用别的Non-gcc编译器(例如Intel C)来编译Linux kernel到底有多轻松/麻烦…
  • 第三行里的trick是,如果代码里尝试將两个不同类型的指针进行比较,编译器会输出一条warning. 例如gcc就会输出warning: comparison of distinct pointer types lacks a cast.

假如你很确定不需要严格的检查类型,就可以用kernel.h里_t结尾的macro,自己指定参数的类型

#define min_t(type, x, y) ({                        \
        	type __min1 = (x);                      \
        	type __min2 = (y);                      \
        	__min1 < __min2 ? __min1: __min2; })

文本替换就是方便…

最后就随手帖拯救懒人嗯…(disqus, jekyll和gist间的相性貌似很差的赶脚= =) source link

#include <stdio.h>

#define min_t(type, x, y) ({                        \
	type __min1 = (x);                      \
	type __min2 = (y);                      \
	__min1 < __min2 ? __min1: __min2; })

/* generate warning if the types are unmatched: "comparison of distinct pointer types lacks a cast" */
#define min(x, y) ({                                \
	typeof(x) _min1 = (x);                  \
	typeof(y) _min2 = (y);                  \
	void) (&_min1 == &_min2);              \ 
	_min1 < _min2 ? _min1 : _min2; })


int main(int argc, char const *argv[])
{
  int a = 12;
  unsigned b = 14;
  printf("min_t: %d\n", min_t(int, a, b));
  printf("min: %d\n", min(a, b));
  return 0;
}

EOF

Make的黑魔术咒文

作为Spellbook,也就是小抄,我才不会介绍make到底是什么呢!