帖子

目前显示的是 四月, 2014的博文

CentOS的gcc版本对比表

CentOS 4.x2005年gcc 3.4CentOS 5.x2007年gcc 4.1CentOS 6.x2011年gcc 4.4CentOS 7.x2014年gcc 4.8这张表对每个做Linux 服务器端开发的C++程序都挺有用的。用来估计代码的兼容性。https://gcc.gnu.org/projects/cxx0x.html

Linux下pthread_t会被快速重用

我最近写的有个程序有点bug,我想加点调试信息,把每个mutex的owner记录下来,谁拿过它,什么时候释放了。然后我意外的发现,pthread_t就跟fd一样,是一个会被快速重用的东西。
测试代码:
#include <iostream> void* f(void* p){ std::cout<<"run"<<std::endl; } intmain(){ pthread_t t1; pthread_create(&t1,NULL,f,NULL); pthread_join(t1,NULL); std::cout<<t1<<std::endl; pthread_t t2; pthread_create(&t2,NULL,f,NULL); pthread_join(t2,NULL); std::cout<<t2<<std::endl; std::cout<<pthread_equal(t1,t2)<<std::endl; return0; } 运行结果:
run
139979191514880
run
139979191514880
1
所以一个更好的替代是使用gettid系统调用,获得线程在内核中的task id。但是,glibc拒绝为此系统调用提供封装,所以只能自己写一个封装:
inline pid_t my_gettid(void){ return syscall(SYS_gettid); } update:Windows下有类似的问题。GetCurrentThreadId()的返回值也是会重复的。我还没找到不重复的替代品。

DIY基于Android的路由器和机顶盒

为什么要DIY为了安全。 目前世面上主流的家用路由器(比如tplink、dlink、netgear)都有内置后门,问题很严重。为了把机顶盒和路由器合在一起。 为了翻墙方便。硬件准备硬件方面我考察了3种方案:cubietruck(即cubieboard3)。基于ARM架构。优点是支持sata、千兆网卡。但是计算能力较弱,CPU是cortex A7双核,内存频率只有480Mhz。售价540左右。Radxa。基于ARM架构。优点是计算能力强,CPU是cortex A9四核1.6GHz,内存DDR3 800MHz。缺点是IO较弱,网卡只有百兆,没有sata接口。售价600左右。Atom D2550。 基于intel x86架构。优点是基于x86,程序安装移植方便,计算能力超强,双以太网卡。整机配好价格大概800-1000左右。最后还是选择了Radxa。目前世面上在售的路由器,除了小米和netgear的某几款是基于ARM,其它的都是基于MIPS芯片组。运算能力远远要弱的多。所以那些把NAS和路由做在一起的,要么选好CPU售价上千,那么就是瞎扯淡。操作系统的考虑 Radxa支持两种操作系统ubuntu和android。两种我都试了一段时间,如果只是做软路由,那么当然是ubuntu更好。用起来就跟x86的linux没啥区别。但是如果还想用它接电视看个视频啥的,那还是android好。随着Android步入客厅,基于android的TV game也许会是一个新兴市场。安装步骤首先在Google Play里面找Terminal Emulator和busybox装上。因为我要用wget来下载ssh server,然后运行。ssh server本来在Google Play里有DroidSSH,好像挺流行的。但是它说什么地区限制,不让我装。我就只好自己编译一个。安装ndk。下载dropbear,然后改若干处。(等我有空把我改过的dropbear 6.2上传到github去)然后编译openssl、squid、unbound等等。我发现很多程序原本就不支持交叉编译,比如squid,它要先编译一个可执行文件,用它生成一个C++的源代码文件,然后把这个新生成的源文件加进去再编译。但是在交叉编译环境中,编译出来的程序是ARM的,我执行gcc的机器是x86的,没办法执行啊!还好这些小问题都可以…

以JIT的方式执行C/C++程序

传统来说,我们编译c/c++程序的方式是:先把每个源文件编译成obj文件$(CXX) -c xxx.cpp -o xxx.o然后把obj文件和其它静态库、动态库链接在一起成为一个可执行文件(ELF/PE)$(CXX) -o xxx xxx1.o xxx2.o xxx3.o -lpthread -lxxxxLLVM加入了一种与机器无关的中间语言IR,使得我们可以像Java一样,半编译半解释的执行C/C++程序。把C/C++源文件编译成LLVM字节码clang在加了-emit-llvm和-c之后,输出的是llvm的bytecode文件(*.bc)例如:$ clang++ -emit-llvm -stdlib=libc++ -fno-use-cxa-atexit -I/data/test2 -o gtest-all.cc.bc -c /data/test2/gtest-all.cc$ clang++ -emit-llvm -stdlib=libc++ -fno-use-cxa-atexit -I/data/test2 -o test.cpp.bc -c /data/test2/test.cppllvm-link能把多个bytecode文件链接成一个bc文件。$ llvm-link test.cpp.bc gtest-all.cc.bc -o hello 执行字节码lli能直接执行bc文件。$ lli -use-mcjit hello.bc 这么做的优点是,bytecode文件只需要生成一次,但是却可以在不同的硬件平台上执行。比如既能在intel x86的CPU上执行,又能在arm上执行。(我已经拿我的RK3188的板子试过)。
程序依赖的额外的动态库可以用-load参数加上。比如$ lli -use-mcjit -load /lib/x86_64-linux-gnu/libssl.so.1.0.0 hello.bc 使用CMake编译不能总停留在Hello World上。要找实际项目做测试。于是我找了curl。它可以通过cmake构建。我先从官网上下载了7.36.0的源代码,然后按正常流程先跑了一次cmake,让它把所有的Makefile和link.txt都生好。但是不执行make指令。然后我修改它原来的CMakeLists.txt,修改其编译规则。在最前…

cortex-a9的运算性能测试

我最近买了一个国产的arm开发板,我想比较一下它和我的台式机的性能差别。最后我觉得,家里自建服务器还是用intel的方案吧,比如DN2800MT之类。ARM只适合移动设备。测试环境:机器1:硬件:mac mini 2012, CPU是i5-3210M CPU @ 2.50GHz,1个物理CPU,双核,超线程,所以在操作系统里看起来是4个CPU。
软件:Ubuntu 13.10 x86_64。 kernel是3.11.0-18-generic。机器2:硬件:radxa开发板。Soc是瑞芯微rk3188,CPU 是4核的cortex-A9@1.6GHz,内存2GB DDR3 @ 800Mhz. 其它详细的硬件信息见这里:http://radxa.com/specification/
软件:Linaro 13.09。C++容器测试:PC的软件环境:编译器: gcc 4.8.1
编译参数:--std=c++11 -mtune=native -march=native -fno-strict-aliasing -O3 -DNDEBUGARM的软件环境:编译器: gcc 4.7.3
编译参数:--std=c++0x -mcpu=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -D__ARM_ARCH=7 -fno-strict-aliasing -O3 -DNDEBUG用一段简单的C++程序,单线程顺序插入1024个整数到std::vector<int>或std::list<int>中,计算耗时。耗费的时间来自getrusage函数。把user mode和kernel mode的总时间加起来。结果:PCARMvector插入1.4亿条每秒3000万条每秒list插入3000万条每秒500万条每秒 由于我的程序是单线程,所以这里比较的是单核的性能。大概有5、6倍的差距。OpenSSL的RSA性能测试:PC的软件环境:OpenSSL 1.0.1e 11 Feb 2013ARM的软件环境:OpenSSL 1.0.1c 10 May 2012测试内容:测试每秒能进行多少次RSA 4096签名或验证RSA 4096签名。这里用的是预编译的包,所以没有针对特定CPU进行优化。结果:PCARM4线程签名/秒216274线程验证/秒13…