【前言】基於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分析。