基于solarflare的openonload技术以TCPDirect方法加速epoll

摘要:
基于solarflare的onload模式加速,官方文档给出TCPDirect模式可以实现从300ns到30ns的延迟缩减。TCPDirect需要拿到源码,并重写底层。我们实现一个类epoll-socket,TCPDirect使用了muxer,实现叫做zocket,进行RTT测试。

【前言】基于solarflare的onload模式加速,官方文档给出TCPDirect模式可以实现从300ns到30ns的延迟缩减。我们需要测试在我们的交易模型框架中他的延时,有人给出了tcpdirect加速大约会比onload模式快300ns左右,不是倍数关系,是一个数量差。虽未达如此高速交易,但量化交易,分秒必争。但是tcpdirect有一个缺点就是必须使用它的接口,不像onload只需要安装好加速环境,使用onload模式就可以了。TCPDirect需要拿到源码,并重写底层。

我们实现一个类epoll-socket,TCPDirect使用了muxer,实现叫做zocket,进行RTT测试。

一、server端

对应epoll,我们使用muxer实现,和epoll接口类似。

1、注意后面要释放掉创建的zf_muxer_free(muxer);

2、因为我们使用内核旁路技术,不要使用zf_recv()函数,虽然他有返回接收数据的大小,但是他是基于copy的,使用zf_zc_recv()。

3、每次在使用接口有数据交换或者使用硬件时,要使用zf_reactor_perform(stack);,因为我们的zocket是运行在一个初始化的stack上的,每次都要用此接口来进行“初始化”,文档这样写的,我也不清楚。

4、其他的和epoll不同之处要悉心,比如无需绑定,用zft_listen()绑定,zf_zc_recv和zf_send的存储的数据结构也不相同,下面有我的两种数据的转换存储方式,因为在服务器端需要进行一个转存;

5、测试时间的核心程序:

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);

二、客户端

1、初始化的stack可能会用完,要加上ZF_TRY(zft_send_space(tcp,&send_size));,send_size是一个传出参数,返回tcp连接的栈剩余空间,小于目标大小的时候要判断,然后重新分配,我们仅是实现测试,足够我用;

2、测试结果,就在客户端。我们需要发送和其他模式下同样的数据,到server,然后返回,client再收到所用的时间。

3、发送和接受和server一样注意,此处无需装换;

4、输出结果的代码,使用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微秒)左右。

基于solarflare的openonload技术以TCPDirect方法加速epoll第1张

具体和普通socket、使用onload加速的对比:

基于solarflare的openonload技术以TCPDirect方法加速epoll第2张

基于solarflare的openonload技术以TCPDirect方法加速epoll第3张

当然,这只是个别。我大约测了10次,平均值大约如此。

三、收获心得

1、学会了初步的gdb- 对于coredump情况调试方法,学会了一些分析错误的思路。

2、tcpdump抓包分析,wireshark分析。

免责声明:文章转载自《基于solarflare的openonload技术以TCPDirect方法加速epoll》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MSSQL临时(tempdb)系统数据库用友GRP-u8 XXE 漏洞复现下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

django的优缺点(非原创)

Django做了很多。使用它快速开发一些Web应用程序是很好的。因此,在一些人眼中,Django只不过是一种灵丹妙药,但对一些人来说,它也是一种毒药和剧毒。Django开发人员也讨论并试图支持SQLAlchemy,但最终放弃了。据估计,成本太高,很难与Django的其他模块集成。尽管Django的ORM不如SQLAlchemy强大,但它并不弱。Django的...

Swift开发中 JSON对象/JSON字符串/Data的互转

本文将介绍常见的转换#pragmark JSON(object)------˃JSON string 1,原生方法//JSON------˃data------˃JSON string letdata=try?JSON序列化。data#pragmark数据------˃JSON(对象)1.本机方法guardletarray=try?[[String:AnyO...

可爱猫+python——定制化微信机器人

框架是模拟真实用户操作,只要不违法乱纪,是不用担心账号冻结问题的。...

H3C交换机如何配置管理VLAN

1.输入“系统视图”(缩写为“sys”)进入系统配置模式[H3C]...

The server selected protocol version TLS10 is not accepted by client preferences [TLS12]

修改jre中的这个文件:/java/jdk1.8/jre/lib/security/java.securityjdk.tls.legacyAlgorithms直接改成下面的这个:jdk.tls.legacyAlgorithms=SSLv3,RC4,DES,MD5withRSA,DHkeySize˂1024,ECkeySize˂224,anon,NULL,in...

vue 调用图片(服务器和本地)

//方法1。直接从“../assets/test.png”//方法2中引入图片作为模块requireimgUrl。将imgUrl放入数据数据(){return{imgUrl:require(“../assets/test.png”)}//方法3。设置数据(){return{imgUrl:...