高CPU使用率-Linux上的简单数据包接收器

高CPU使用率-Linux上的简单数据包接收器,linux,networking,cpu-usage,Linux,Networking,Cpu Usage,我正在Linux下编写一个简单的应用程序,它收集来自网络的所有数据包。我通过调用“recvfrom()”函数来使用阻塞接收。当我使用hping3(每秒约100k原始帧,每个130字节)生成较大的网络负载时,“top”工具显示我的进程的CPU使用率很高,约为37-38%。这对我来说很有价值。当我减少数据包数量时,使用率会降低-例如,对于每秒4k帧,top显示3%。 我已经检查过DC++在下载~10MB/s时的性能,它的进程占用的CPU不是38%,而是5%。在C语言中,是否有任何可编程的方法来减少C

我正在Linux下编写一个简单的应用程序,它收集来自网络的所有数据包。我通过调用“recvfrom()”函数来使用阻塞接收。当我使用hping3(每秒约100k原始帧,每个130字节)生成较大的网络负载时,“top”工具显示我的进程的CPU使用率很高,约为37-38%。这对我来说很有价值。当我减少数据包数量时,使用率会降低-例如,对于每秒4k帧,top显示3%。
我已经检查过DC++在下载~10MB/s时的性能,它的进程占用的CPU不是38%,而是5%。在C语言中,是否有任何可编程的方法来减少CPU的使用并仍然接收大量的帧

我的CPU: 英特尔i5-2400 CPU@3.10Ghz

我的系统: Ubuntu 11.04内核3.6.6,带有PREEMPT-RT补丁

这是我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <linux/if_arp.h>
#include <arpa/inet.h>

/* Socket descriptor. */
int mainSocket; 

/* Buffer for frame. */
unsigned char* buffer;

int main(int argc, char* argv[])
{
    /** Create socket. **/  
    mainSocket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (mainSocket == -1) { 
        printf("Error: cannot create socket!\n");
    }

    /** Create buffer for frame **/
    buffer = malloc(ETH_FRAME_LEN);

    printf("Listing...");

    while(1) {

        // Length of received packet
        int length = recvfrom(mainSocket, buffer, ETH_FRAME_LEN, 0, NULL, NULL);
        if(length > 0) 
        {   
            // ... do something ...
        }
    }
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*套接字描述符*/
int主插座;
/*帧缓冲区*/
无符号字符*缓冲区;
int main(int argc,char*argv[])
{
/**创建套接字。**/
mainSocket=socket(AF_数据包、SOCK_原始、htons(ETH_P_ALL));
如果(mainSocket==-1){
printf(“错误:无法创建套接字!\n”);
}
/**为帧创建缓冲区**/
缓冲区=malloc(以太帧长度);
printf(“列表…”);
而(1){
//接收数据包的长度
int length=recvfrom(mainSocket,buffer,ETH\u FRAME\u LEN,0,NULL,NULL);
如果(长度>0)
{   
//…做点什么。。。
}
}

可能是因为,运行在NIC和DC++上的TCP/IP堆栈直接从NIC获取数据流,所以您的处理器没有执行任何TCP/IP工作。但在您的情况下,我认为您是直接尝试从NIC获取数据,所以它不会由NIC处理,而是由您的处理器处理。由于您有无限循环来获取数据,因此您需要执行大量的pr处理…因此CPU使用率急剧上升。

我不知道这是否有帮助,但在谷歌上我看到:

  • 以及使用
    PACKET_MMAP
    MMAP()
    来提高原始套接字的性能

  • 建议将进程的关联性设置为与您所使用的CPU相匹配


DC++
是否进行了杂乱的接收?我不会猜到。因此,与其将您的性能与
DC++
进行比较,不如将您的性能与
libpcap

等实用程序的性能进行比较是的,它应该很有用,尤其是mmap()最后,我已经实现了mmap(),主循环现在正在处理simple poll()函数(我使用了这个示例)当我每秒接收100k帧时,它只给了我约4%的提升。我的应用程序取决于NIC生成的中断数量。我仍在考虑如何改进我的代码。。