为什么同一个函数的执行时间不同?

时间:2017-04-12 16:49:23

标签: c++ performance tcp serial-port udp

我有一个设置,我通过串行或以太网连接从Windows笔记本电脑向Raspberry Pi发送数据(一次1个字节)。然后,Pi通过串行或以太网将数据发送回笔记本电脑,并记录往返时间的传输。 Raspberry Pi服务器使用C ++编写。

现在我正在尝试测量Raspberry Pi端接收和发送的执行时间。但是,我注意到相同的功能(在串行端口上接收)具有不同的执行时间,具体取决于是使用UDP还是TCP来发回数据。这对我来说没有意义,我认为无论如何在串口上接收都是一样的。

如有必要,我可以发布实际代码。谁能帮忙解释一下这里发生了什么?这是计时器的不准确吗?我正在使用chrono库进行毫秒计时。

以下是代码:

void send_client_udp( char *s, int mysock, int myport){
int i;
for(i=0;i<BACKLOG;i++){

        if(htons(udparray[i].sin_port) == myport){
            sendto(mysock,s,1,0,(struct sockaddr*)&udparray[i], sizeof udparray[i]);
        }

}
}

 void send_message_all_udp(char *s, int mysock){
int k;
for(k=0;k<BACKLOG;k++){

        sendto(mysock,s,1,0,(struct sockaddr*)&udparray[k], sizeof udparray[k]);

}
}
 void send_client_tcp( char *s, int mysock){
int i;
for(i=0;i<BACKLOG;i++){
    if(tcparray[i]){
        if(tcparray[i] == mysock){
            send(tcparray[i], s, 1,0);
        }
    }
}
} 

/* Send message to all clients */
void send_message_all_tcp(char *s){
int k;
for(k=0;k<BACKLOG;k++){
    if(tcparray[k]){
        send(tcparray[k], s, 1,0);
    }
}
}

void *sr_es_udp(void *thissock)
{
  int mysock = *(int*)thissock;
 int counter = 1;
int ardint;
char ardchar;
char *mesg;
while (ardrun)

{
if (serialDataAvail (serfd) == -1)
{
    fprintf(stdout, "(Serial) No data able to be received: %s\n", strerror (errno));
    exit(EXIT_FAILURE);
} 
auto recv1 = chrono::high_resolution_clock::now();
ardint = serialGetchar(serfd) ;
auto recv2 = chrono::high_resolution_clock::now();
   if (ardint > 0)
{

 ardchar = char(ardint);
 mesg = &ardchar;

 send_message_all_udp(mesg, mysock); 
 auto sendcli = chrono::high_resolution_clock::now();
 std::chrono::duration<double,std::milli> elapscli = (sendcli - recv2);
 std::chrono::duration<double,std::milli> elapsrecv = (recv2 - recv1);
 outfile << counter << "\t" << elapsrecv.count() << "\t"<< elapscli.count() << "\t" << ardint << "\n";
 counter++;
}

}
cout << "exit" << endl;
exitard= true;
}


 void *er_es_udp(void *pnewsock)
{
int mysock = *(int*)pnewsock;
char client_msg[MAXLEN];
int read_size;

int clientint;
int myport;
 int counter = 1;  
 while(looprun){
  auto recv1 = chrono::high_resolution_clock::now();                      
  read_size = recvfrom(mysock, client_msg, 1, 0, (struct sockaddr*)&their_addr, &size);
  auto recv2 = chrono::high_resolution_clock::now();

 clientint = int(*client_msg);

 myport = htons(their_addr.sin_port);
if (clientint >0)
{



serialPuts (serfd, &(*client_msg)) ;
auto sendser = chrono::high_resolution_clock::now();

send_client_udp(client_msg,mysock,myport); 
auto sendcli = chrono::high_resolution_clock::now();
std::chrono::duration<double,std::milli> elapsrecv = recv2-recv1;
std::chrono::duration<double,std::milli> elapscli = sendcli-recv2;
std::chrono::duration<double,std::milli> elapsser = sendser-recv2;
//outfile << counter << "\t" << elapsrecv.count() << "\t" << elapsser.count() << "\t" << clientint << "\n";
outfile << counter << "\t" << elapsrecv.count() << "\t" << elapscli.count() << "\t" << elapsser.count() << "\t" << clientint << "\n";
counter++;
}


}
 cout << "exit " << endl;


}

/* TCP data handling */
void *sr_es_tcp(void *)
{

int counter = 1;
int ardint;
char ardchar;
char *mesg;
while (run)

{
if (serialDataAvail (serfd) == -1)
{
    fprintf(stdout, "(Serial) No data able to be received: %s\n", strerror (errno));
    exit(EXIT_FAILURE);
} 
 auto recv1 = chrono::high_resolution_clock::now();       
 ardint = serialGetchar (serfd) ;
 auto recv2 = chrono::high_resolution_clock::now();
 if (ardint > 0)
 {
    ardchar = char(ardint);
  mesg = &ardchar;


 send_message_all_tcp(mesg);
auto sendcli = chrono::high_resolution_clock::now();
std::chrono::duration<double,std::milli> elapscli = (sendcli - recv2);
 std::chrono::duration<double,std::milli> elapsrecv = (recv2 - recv1);
 outfile << counter << "\t" << elapsrecv.count() << "\t"<< elapscli.count() << "\t" << ardint << "\n";
 counter++;

}

}
cout << "exit" << endl;
exitard=true;
}

/* handle the connections from client */
void *er_es_tcp(void *pnewsock)
{
int mysock = *(int*)pnewsock;


 char client_msg[MAXLEN];

 int read_size;

 int clientint;

  int myport;
  int counter = 1;

  while(looprun){   

  read_size = recv(mysock, client_msg, 1, 0);

  auto recv2 = chrono::high_resolution_clock::now();
   clientint = int(*client_msg);


    if (clientint > 0)
   {
client_msg[read_size] = '\0';


 serialPuts(serfd, &(*client_msg)) ;
  auto sendser = chrono::high_resolution_clock::now();

 send_client_tcp(client_msg,mysock); //was send_message

 auto sendcli = chrono::high_resolution_clock::now();


 std::chrono::duration<double,std::milli> elapsrecv = recv2-recv1;
std::chrono::duration<double,std::milli> elapscli = sendcli-recv2;
std::chrono::duration<double,std::milli> elapsser = sendser-recv2;


 outfile << counter  << "\t" << elapscli.count() << "\t" << elapsser.count() << "\t" << clientint << "\n";
  counter++;
  }


  }
  cout << "exit " << endl;



}

对于sr_es函数,serialGetChar执行时间根据send_message_all是UDP还是TCP而变化。 serialGetChar来自WiringPi串行库。另外,Eth_recv_eth_send()中的send_message_client_tcp对于TCP的Ser_recv_eth_send()中的send_message_all_tcp是不同的,特别是当serialGetChar以115200bps接收时,与9600bps相比。为什么会这样?只有一个客户端,因此send_message_client_tcp()和send_message_all_tcp()应该相同。无论串口波特率如何,都不应该发送tcp一致,为什么串口接收时间因互联网协议而改变?

以下是几项不同测试的平均值和标准偏差(每次1000个数据点的10次试验):

通过以太网接收/发送

  1. UDP接收:0.5 +/- 0.37 ms,UDP发送:0.30 +/- 0.17 ms
  2. TCP接收:0.44 +/- 0.4 ms,TCP发送:0.39 +/- 0.15 ms
  3. 系列接收,通过以太网发送

    1. 串口波特9600接收:4.3 +/- 0.1 ms,UDP发送:0.25 +/- 0.11 ms
    2. 串行波特9600接收:3.9 +/- 0.1ms,TCP发送:0.77 +/- 0.19ms - &gt;有趣的是,前30个左右的点位于0.35,此后它的射程达到~0.75-1 ms
    3. 串口波特115200接收:0.3 +/- 0.09 ms,UDP发送:0.23 +/- 0.11 ms
    4. 串口波特115200接收:1 +/- 0.15 ms,TCP发送:0.34 +/- 0.1 ms

0 个答案:

没有答案