分配缓冲区的差分方法中的以太网吞吐量下降

时间:2014-08-08 00:30:01

标签: c++ embedded-linux serversocket ethernet

我们在服务器代码上尝试了以下方法,并且吞吐量结果非常糟糕。编码风格和内存分配是否会影响吞吐量性能?我们如何调整它?我需要达到至少55%以上。我使用wireshark测试我的吞吐量,我做了一些设置: 服务器

   ethtool -K eth0 tx off
   ifdown eth0
   ifconfig eth0 mtu 3500
   ifup eth0
   taskset -c 0 ./server

客户端

  ifconfig eth0 mtu 9000
  1. 阵 一个。没有填充任何数据。

    unsigned long bytetosent = 4080*65536;
    char sendBuff[4080 * 65536];
    while(x < bytetosent)               
    {
       int bytesWritten = send(connfd, (const char*)sendBuff+x, 6144, 0);
       x += 6144;
    }
    
  2. 吞吐量:73%

    湾填充随机数据

        for(int y=0; y<(4080); y++)
        {
          sendBuff[y] = (rand() %255);
        }
        while(x < bytetosent)               
        {
           int bytesWritten = send(connfd, (const char*)sendBuff+x, 6144, 0);
           x += 6144;
        }
    

    吞吐量:53%

    1. MMAP

      pImagePool = mmap( (void *)DDR_RAM_PHYS,MAPPED_SIZE_BUFFER, PROT_READ, MAP_SHARED, _fdMem, 0);
      while(x < bytetosent)
      {
        bytesWritten =send(connfd, ((const char*)(pImagePool))+ x, 6144, 0);
        x += 6144;
      }
      
    2. 吞吐量:20%

      1. 的malloc

        char *_mBuffer;
        _mBuffer = malloc(4080 * 65536);
        
      2. 一个。没有填充任何数据

            while(x < bytetosent)
            {
                bytesWritten =send(connfd, (const char*)_mBuffer+x, 6144, 0);
                x += 6144;
            }
        

        吞吐量:73%

        湾填充随机数据 吞吐量:50%

        1. 矢量

          vector<char>_pBuffer;
          

          一个。复制

          copy((char*)(pImagePool), (((char*)(pImagePool))+1000000), back_inserter(_pBuffer));
          bytesWritten = send(connfd, &_pBuffer[bytesSent], bytetosent, MSG_CONFIRM);
          bytesSent += bytesWritten;
          
        2. 吞吐量:非常慢

          湾的push_back

             for(int y=0; y<bytetosent; y++)
             {
               _pBuffer.push_back(*((char*)pImagePool+y));                   
             }
          

          吞吐量:非常慢

          我的服务器连接设置代码:

              int listenfd = 0, connfd = 0;
              struct sockaddr_in serv_addr;
              time_t ticks;
              listenfd = socket(AF_INET, SOCK_STREAM, 0);
              memset(&serv_addr, '0', sizeof(serv_addr));
              serv_addr.sin_family = AF_INET;
              serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
              serv_addr.sin_port = htons(8080);
              bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
              listen(listenfd, 10);
              connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
          

          我的客户收到代码:

             char recvBuff[4080 * 65536];
             while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
             {
               recvBuff[n] = 0;
                  //printf("\n in while\n");
               if(0)//fputs(recvBuff, stdout) == EOF)
               {
                 printf("\n Error : Fputs error\n");
               }
             }
          

          我尝试使用mmap和memcpy进行时间分析。结果: 它考虑快?

          总字节数:40000 * 1088 拍摄时间:0.107197s

          代码:

              void *pImagePool;
              char _cpy[40000 * 1088];
              /*Memory Mapping */
              const char imagePoolDevice[]="/dev/mem";
              int _fdMem;
              if( (_fdMem = open( imagePoolDevice, O_RDWR | O_SYNC )) < 0 )
              {
               printf("Unable to open /dev/mem %d\n", _fdMem);
              }
              //start
              start = chrono::system_clock::now();
              pImagePool = mmap(0,MAPPED_SIZE_BUFFER, PROT_READ|PROT_WRITE, MAP_SHARED, _fdMem, DDR_RAM_PHYS);
             if( pImagePool == MAP_FAILED ){printf("Mapping Failed\n");}
             else{printf("Successful Mapping\n");}
              memcpy ( _cpy, &pImagePool, sizeof(_cpy));
              //end
              end = chrono::system_clock::now();
              chrono::duration<double>elapsed_seconds = end - start;
              time_t end_time = chrono::system_clock::to_time_t(end);
              cout<<"mmap time taken = "<<elapsed_seconds.count()<<endl;
          

1 个答案:

答案 0 :(得分:0)

我终于通过盲测来克服了这个问题,我用以下两种方法进行测试:

  1. 我创建一个数组并记忆mmap返回指向数组的指针。它将以太网吞吐量提高了55%。代码如下所示:

    char _cpy[40000 * 1088];
    pImagePool = mmap(0,MAPPED_SIZE_BUFFER, PROT_READ|PROT_WRITE, MAP_SHARED, _fdMem, DDR_RAM_PHYS);
    memcpy ( _cpy, pImagePool, 40000 * 1088);
    while(bytesSent != bytetosent)
    {
       bytesWritten = send(connfd, &_cpy[bytesSent], bytetosent, MSG_CONFIRM);
       bytesSent += bytesWritten;
    }
    
  2. 复制mmap返回指向vector的指针,但需要先保留矢量大小。很抱歉,我没有在我以前的测试代码中正确执行。以太网吞吐量增加到51%。

    vector<char>_pBuffer;
    pImagePool = mmap(0,MAPPED_SIZE_BUFFER, PROT_READ|PROT_WRITE, MAP_SHARED, _fdMem, DDR_RAM_PHYS);
    _pBuffer.reserve(43520000); //40000 * 1088
    copy((char*)pImagePool, (char*)pImagePool + 43520000, back_inserter(_pBuffer));
    while(bytesSent != bytetosent)
    {
        bytesWritten = send(connfd, &_pBuffer[bytesSent], bytetosent, MSG_CONFIRM);
        bytesSent += bytesWritten;
    }
    
  3. 我不知道这个方法是如何工作的,我只是假设它是复制到内存缓存。