【前言】基于solarflare的onload模式加速,官方文档给出TCPDirect模式能够实现从300ns到30ns的延迟缩减。咱们须要测试在咱们的交易模型框架中他的延时,有人给出了tcpdirect加速大约会比onload模式快300ns左右,不是倍数关系,是一个数量差。虽未达如此高速交易,但量化交易,分秒必争。可是tcpdirect有一个缺点就是必须使用它的接口,不像onload只须要安装好加速环境,使用onload模式就能够了。TCPDirect须要拿到源码,并重写底层。html
咱们实现一个类epoll-socket,TCPDirect使用了muxer,实现叫作zocket,进行RTT测试。react
对应epoll,咱们使用muxer实现,和epoll接口相似。c++
一、注意后面要释放掉建立的zf_muxer_free(muxer);sql
二、由于咱们使用内核旁路技术,不要使用zf_recv()函数,虽然他有返回接收数据的大小,可是他是基于copy的,使用zf_zc_recv()。mongodb
三、每次在使用接口有数据交换或者使用硬件时,要使用zf_reactor_perform(stack);,由于咱们的zocket是运行在一个初始化的stack上的,每次都要用此接口来进行“初始化”,文档这样写的,我也不清楚。服务器
四、其余的和epoll不一样之处要悉心,好比无需绑定,用zft_listen()绑定,zf_zc_recv和zf_send的存储的数据结构也不相同,下面有个人两种数据的转换存储方式,由于在服务器端须要进行一个转存;数据结构
五、测试时间的核心程序:框架
ZF_TRY(zf_muxer_add(muxer, zft_to_waitable(zock), &evs[i])); //初始化stack zf_reactor_perform(stack); rd1.zcr.iovcnt = 1; HP_TIMING_NOW(t0); zft_zc_recv(zock, &rd1.zcr, 0); if( rd1.zcr.iovcnt == 0 ) continue; if( first_recv ) { first_recv = 0; siov.iov_len = rd1.zcr.iov[0].iov_len; memcpy(buf, ((char*)rd1.zcr.iov[0].iov_base),siov.iov_len); } for( int i = 0 ; i < rd1.zcr.iovcnt; ++i ) { len3=zft_send(zock, &siov, 1, 0); } HP_TIMING_NOW(t1); //c++11的元组,编译时候可能要加上-std=c++11 time_v.push_back(std::make_tuple(len3,t1, t0, (t1 - t0))); cout<<"服务器发送:"<<len3<<"数据:"<<buf<<endl; zft_zc_recv_done(zock, &rd1.zcr);
一、初始化的stack可能会用完,要加上ZF_TRY(zft_send_space(tcp,&send_size));,send_size是一个传出参数,返回tcp链接的栈剩余空间,小于目标大小的时候要判断,而后从新分配,咱们仅是实现测试,足够我用;nosql
二、测试结果,就在客户端。咱们须要发送和其余模式下一样的数据,到server,而后返回,client再收到所用的时间。socket
三、发送和接受和server同样注意,此处无需装换;
四、输出结果的代码,使用tuple。mongodb那种nosql能够用这种数据组织方式存储。
std::vector<std::tuple<int, u64_t, u64_t, int>>::iterator it; for (it = time_v.begin(); it != time_v.end(); ++it) { cout << "len=" << std::get<0>(*it) << " --- recv time = " << std::get<1>(*it) << ", send time = " << std::get<2>(*it) << ", gap = " << std::get<3>(*it) << endl; if (it != time_v.begin()) { sum += std::get<3>(*it); ++num; } }
#第一个时间是jiffies,要除以本机的cpu主频
std::cout << "avg gap = " << (sum / (num*1.0) ) << endl;
std::cout << "avg gap(ns) = " << (sum / (num*3.4)) << endl;
(关于jiffies和cpu频率的关系:https://www.cnblogs.com/by-dream/p/5143192.html 相除就是时间)
使用tcpdirect在char类型511字节数据上,进行RTT测试,循环1000次的平均用时3444纳秒(3.5微秒)左右。
具体和普通socket、使用onload加速的对比:
固然,这只是个别。我大约测了10次,平均值大约如此。
一、学会了初步的gdb- 对于coredump状况调试方法,学会了一些分析错误的思路。
二、tcpdump抓包分析,wireshark分析。