04 2009存档
周末从虚拟机上传文件,需要用到一个ftp的客户端,马上想起了leapftp,于是在自己的文件夹里翻了一遍,找到了,看日期,2003年的,应该是本科毕业前拷的。不过自打离开学校就再没用过了。
在学校的时候,ftp是当时几乎唯一的文件交流方式,连下载个pdf reader,弄个电子书都是用ftp,本科毕业以后在租的房子里上网,最大最大的问题就是没地方下载,尤其是电影和游戏,动辄600MB,直接从网页下 载那要等到花儿都谢了。那时bt下载刚刚兴起,找种子也是个费劲的事,记得有一次看到一个发布种子的论坛,可惜人家不公布种子链接,要有足够积分才行,某 网友留贴说“谁可怜可怜,转让点积分吧,唉,一个种子都看不了,呜呜”,我看了也是同病相怜,觉得一离开学校就什么资源都没了,跟个乞丐似的。
后来网络高速发展了,找BT种子很方便,甚至在线看电影都可以(不过我也不怎么爱看电影打游戏了),ftp更是老黄历了(也许学校里还在用),还是工作了好,学校里面太没意思了(其实主要是没钱)。
在学校的时候,ftp是当时几乎唯一的文件交流方式,连下载个pdf reader,弄个电子书都是用ftp,本科毕业以后在租的房子里上网,最大最大的问题就是没地方下载,尤其是电影和游戏,动辄600MB,直接从网页下 载那要等到花儿都谢了。那时bt下载刚刚兴起,找种子也是个费劲的事,记得有一次看到一个发布种子的论坛,可惜人家不公布种子链接,要有足够积分才行,某 网友留贴说“谁可怜可怜,转让点积分吧,唉,一个种子都看不了,呜呜”,我看了也是同病相怜,觉得一离开学校就什么资源都没了,跟个乞丐似的。
后来网络高速发展了,找BT种子很方便,甚至在线看电影都可以(不过我也不怎么爱看电影打游戏了),ftp更是老黄历了(也许学校里还在用),还是工作了好,学校里面太没意思了(其实主要是没钱)。
小钢炮代码大赛入围
董昊: 正好,入围的就奖一个4G u盘,你可以补充一下
小钢炮: 我不需要 U 盘了 ...
董昊: 移动硬盘?....这个女队才有这个奖啊,难道我们要化妆?
董昊: 正好,入围的就奖一个4G u盘,你可以补充一下
小钢炮: 我不需要 U 盘了 ...
董昊: 移动硬盘?....这个女队才有这个奖啊,难道我们要化妆?
上本科的时候学过java,后来打零工还写了三个多月的java代码,后来觉得java太贴近业务,而业务很乱很无聊,所以就不再做java类的活。
前几年用过MySQL,布master/slave,启动多个server....都折腾过不少,后来系统越来越大,公司就换用自己开发的key/value存储库,抛弃MySQL了。不过总体感觉MySQL还是很不错的,简洁高效。
研究OS的那阵听说过Solaris,后来它开源了,实在替SUN觉得心疼——前后十亿美金投资开发的操作系统,就这么裸奔了。至今没有用过Solaris,但是很仰慕,毕竟是早期强悍的Unix之一。
找实习的时候曾经参加过SUN工程院的招聘,二十个人左右参加笔试,我总算还进了面试,但被“lock指令由几条微指令组成”问倒,没有应聘成功。
还说这些旧事干嘛呢?SUN都没了。
前几年用过MySQL,布master/slave,启动多个server....都折腾过不少,后来系统越来越大,公司就换用自己开发的key/value存储库,抛弃MySQL了。不过总体感觉MySQL还是很不错的,简洁高效。
研究OS的那阵听说过Solaris,后来它开源了,实在替SUN觉得心疼——前后十亿美金投资开发的操作系统,就这么裸奔了。至今没有用过Solaris,但是很仰慕,毕竟是早期强悍的Unix之一。
找实习的时候曾经参加过SUN工程院的招聘,二十个人左右参加笔试,我总算还进了面试,但被“lock指令由几条微指令组成”问倒,没有应聘成功。
还说这些旧事干嘛呢?SUN都没了。
#include <stdint.h>
struct tdb
{
uint32_t c;
uint64_t a;
uint64_t b;
};
64位系统默认按8个字节来align,所以tdb的第一个成员c会align成8个字节。这个struct在32位gcc上编译后的size是20个字节, 而在64位上的size是24个字节,这个struct tdb是要写入文件的(实际上是通过mmap),这下就不能通用了。解决办法之一是加再加一个uint32_t的成员来“填充”这个空缺:
struct tdb
{
uint32_t c;
uint32_t align;
uint64_t a;
uint64_t b;
};
同样的
struct page
{
ushort c;
uint64_t a;
};
也要改为
struct page
{
ushort b;
ushort align1;
uint32_t align2;
uint64_t a;
};
这是“手工”的方法,其实还有更方便的,就是gcc的attribute修饰符:
struct page __attribute__ ((__packed__))
{
ushort c;
uint64_t a;
};
这样不管实在32位还是64位机器上,struct page的大小都是10个字节。
struct tdb
{
uint32_t c;
uint64_t a;
uint64_t b;
};
64位系统默认按8个字节来align,所以tdb的第一个成员c会align成8个字节。这个struct在32位gcc上编译后的size是20个字节, 而在64位上的size是24个字节,这个struct tdb是要写入文件的(实际上是通过mmap),这下就不能通用了。解决办法之一是加再加一个uint32_t的成员来“填充”这个空缺:
struct tdb
{
uint32_t c;
uint32_t align;
uint64_t a;
uint64_t b;
};
同样的
struct page
{
ushort c;
uint64_t a;
};
也要改为
struct page
{
ushort b;
ushort align1;
uint32_t align2;
uint64_t a;
};
这是“手工”的方法,其实还有更方便的,就是gcc的attribute修饰符:
struct page __attribute__ ((__packed__))
{
ushort c;
uint64_t a;
};
这样不管实在32位还是64位机器上,struct page的大小都是10个字节。
尽管intel中国有压榨软件学院实习生的恶迹,但抛开这些不说,intel的编译器和性能分析工具还是相当不赖。以前就在《程序员》杂志上看到
说intel编译器不仅优化代码的能力出众,而且对于代码中可以化为并行的部分会自动帮你编译为可并行执行的指令....简直是出神入化。
前一阵下载了intel编译器的evaluation版试了试,性能的确能提高30-10%左右。
最大的发现是intel编译器附带自己的c语言库,比如对于内存操作类的函数叫_intel_fast_memcpy, _intel_fast_memset, _intel_fast_memcmp等,由编译器加进object文件里。gcc的memcpy是一个byte一个byte的拷贝,而intel的_intel_fast_memcpy我估计是像linux内核的 __memcpy一样,先一个int(4个字节)一个int的拷,不够4个字节了,再一个short(2个字节)一个short的拷,最后如果剩一个字 节,单独拷它。因为movw花的时间肯定不到movb的四倍,所以这种分粒度的拷贝肯定更高效。当然,也不排除intel编译器另外用了什么高级指令,让 内存拷贝更快——类似MMX里面的矩阵乘法。
前一阵下载了intel编译器的evaluation版试了试,性能的确能提高30-10%左右。
最大的发现是intel编译器附带自己的c语言库,比如对于内存操作类的函数叫_intel_fast_memcpy, _intel_fast_memset, _intel_fast_memcmp等,由编译器加进object文件里。gcc的memcpy是一个byte一个byte的拷贝,而intel的_intel_fast_memcpy我估计是像linux内核的 __memcpy一样,先一个int(4个字节)一个int的拷,不够4个字节了,再一个short(2个字节)一个short的拷,最后如果剩一个字 节,单独拷它。因为movw花的时间肯定不到movb的四倍,所以这种分粒度的拷贝肯定更高效。当然,也不排除intel编译器另外用了什么高级指令,让 内存拷贝更快——类似MMX里面的矩阵乘法。
之前用了Berkeleydb的DB_THREAD标记,于是bdb的增删查都内部带锁,但最近发现有内存泄漏的嫌疑——即使只调用bdb的del,用
free看系统剩下的内存也会越来越少,后来才发现问题:原来一旦用了DB_THREAD标记,在
db->get,db->put,db->del
时操作的DBT必须带上DB_DBT_USERMEM或DB_DBT_MALLOC,以告知bdb是用户程序来分配内存还是bdb自己来分配内存给DBT
key和DBT value。
即使是del操作,也必须写清楚这个flag:
char buff[64];
// buff中是要删除的key
....
DBT tKey;
memset(&tKey,0,sizeof(DBT));
tKey.flags = DB_DBT_USERMEM;
tKey.data = buff;
tKey.size = strlen(buff);
int res = m_dbp->del(m_dbp,NULL,&tKey,0);
这样就没有所谓的“内存泄漏”了。
即使是del操作,也必须写清楚这个flag:
char buff[64];
// buff中是要删除的key
....
DBT tKey;
memset(&tKey,0,sizeof(DBT));
tKey.flags = DB_DBT_USERMEM;
tKey.data = buff;
tKey.size = strlen(buff);
int res = m_dbp->del(m_dbp,NULL,&tKey,0);
这样就没有所谓的“内存泄漏”了。