歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 報文處理中的主動和被動輪詢

報文處理中的主動和被動輪詢

日期:2017/2/28 14:25:43   编辑:Linux教程

如果你希望避免浪費CPU循環,當你沒有事情做時(例如,沒有報文等待處理),你應該調用pfring_poll()進行輪詢,當有報文需要處理時要求系統喚醒程序。如果你創建一個主動輪詢循環時,你可能希望做一些事情,就像下面:

while(<no packet available>) {usleep(1); }

減少CPU循環花費(理論上)一小會(1ms)時間,最佳的實踐是usleep()指定的持續時間(或者你希望使用nanosleep()替代usleep())。不幸的是,這並非如此。這些函數使用系統調用來實現sleep。一個簡單的系統調用的開銷相當低(例如,你能使用時間系統調用的測試程序測試它),每個調用通常會小於100ns,比我們希望的1us休眠更少。現在讓我們測量下usleep()和nanosleep()的精度,使用簡單的程序(sleep.c)。

#include <string.h>

#include <sys/time.h>

#include <stdio.h>

double delta_time_usec(struct timeval *now,struct timeval *before) {

time_t delta_seconds;

time_t delta_microseconds;

delta_seconds =now->tv_sec - before->tv_sec;

if(now->tv_usec > before->tv_usec)

delta_microseconds = now->tv_usec - before->tv_usec;

else

delta_microseconds = now->tv_usec - before->tv_usec +1000000; /* 1e6 */

return((double)(delta_seconds * 1000000) + (double)delta_microseconds);

}

int main(int argc, char* argv[]) {

inti, n = argc > 1 ? atoi(argv[1]) : 100000;

static struct timeval start, end;

struct timespec req, rem;

inthow_many = 1;

gettimeofday(&start, NULL);

for(i = 0; i < n; i++)

usleep(how_many);

gettimeofday(&end, NULL);

printf("usleep(1) took %f usecs\n", delta_time_usec(&end,&start) / n);

gettimeofday(&start, NULL);

for(i = 0; i < n; i++) {

req.tv_sec = 0, req.tv_nsec = how_many;

nanosleep(&req, &rem);

}

gettimeofday(&end, NULL);

printf("nanosleep(1) took %f usecs\n",delta_time_usec(&end, &start) / n);

}

結果是不同的機器稍有變化,但是他們大約都在60usec左右。

# ./sleep

usleep(1) took 56.248760 usecs

nanosleep(1) took 65.165280 usecs

這意味著使用usleep和nanosleep休眠1ms時,實際上它們休眠了大約60ms。該結果不是很驚訝,其它人早就發現了這個問題。

在實際中這意味著什麼呢?我們知道在10G線速下,67ns要接收一個報文,休眠60usec意味著在這段時間中你可接收大約895個報文,你必須有更多的緩沖處理這種情況,否則會出現丟包的情況。它也表示你不能做任何輪詢,除了在緊急情況下使用純粹的主動輪詢(例如:在主動報文輪詢中不進行任何的usleep/nanosleep),例如:當你從兩個網絡適配器上對報文進行時間合並時。

總結:主動輪詢不是很優雅,但是在高速下處理報文可能是強制性的,為了達到高速和精確的要求。PF_RING應用支持主動和被動輪詢。例如你使用的pfcount使用-a標識強制使用主動報文輪詢,因此(有些情況下)增加報文捕獲性能,代價是導致你的CPU核利用率100%(例如:當你使用主動輪詢時確保你也綁定你的應用到一個核上,在pfcount中你可以使用-g來完成)。

參考文檔

[1] PF_RING ZC(零拷貝)簡介

http://www.ntop.org/pf_ring/introducing-pf_ring-zc-zero-copy/

[2] 不是所有服務器都一樣(DNA)三部分

http://www.ntop.org/pf_ring/not-all-servers-are-alike-with-dna/

http://www.ntop.org/pf_ring/not-all-servers-are-alike-with-pf_ring-zcdna-part-2/

http://www.ntop.org/pf_ring/not-all-servers-are-alike-with-pf_ring-zcdna-part-3/

[3] 應用之間如何使用PF_RING平衡流量

http://www.ntop.org/pf_ring/how-to-balance-mobile-traffic-across-applications-using-pf_ring/

[4] 使用n2disk和PF_RING構建一個廉價的2*10Gbit(繼續)報文記錄器

http://www.ntop.org/n2disk/building-a-cheap-2x10-gbit-continuous-packet-recorder-using-n2disk-and-pf_ring/

Copyright © Linux教程網 All Rights Reserved