fprintf 对时间戳计数器有奇怪的影响

fprintf have strange effect on timestamp counter

我有两个计数器:

#define number_of_ccr 1024
unsigned int lpBuffer[number_of_ccr] = {0};
unsigned long nNumberOfBytesToRead =     number_of_ccr*4;
unsigned long lpNumberOfBytesRead;  
unsigned int counter = 0;
unsigned int error = 0;
QueryPerformanceCounter(&fullCounter); // first counter

for(;;) {

  QueryPerformanceCounter(&startCounter); //     second counter 
  error = ReadFile(
    hSerial,
    lpBuffer,
    nNumberOfBytesToRead,
    &lpNumberOfBytesRead,
    NULL
    );

  if(!strcmp(lpBuffer, "end")) {
  CloseHandle(FileHandle);
  //char *copyString = "copy";
  //WriteFile(hSerial, copyString , strlen(copyString), &bytes_written, NULL);
  fprintf(stderr, "end flag was received\n");
  break;
  }
  else if(lpNumberOfBytesRead == nNumberOfBytesToRead) {

  // NOTE(): succeed
  QueryPerformanceCounter(&endCounter);
  time += Win32GetSecondsElapsed(startCounter, endCounter); //second counter

  DWORD BytesWritten;
  // write data to file
  WriteFile(FileHandle, lpBuffer, lpNumberOfBytesRead, &BytesWritten, 0);
    if(!(lpBuffer[0] % 1024)) {
      fprintf(stderr, "bytes %d \r", lpBuffer[0]);// <--- THIS LINE
    }
  }
  else if(lpNumberOfBytesRead < nNumberOfBytesToRead) {
    fprintf(stderr, "bytes %d \n", lpNumberOfBytesRead); 
  }

}// for(;;) 
QueryPerformanceCounter(&fullCounterEnd);
fullTime =   Win32GetSecondsElapsed(fullCounter, fullCounterEnd);           

char DebugBuffer[256];
fprintf(stderr, "time: %f \n", time);
fprintf(stderr, "full time: %f \n", fullTime);

如果我要评论 fprintf(stderr, "bytes %d \r", lpBuffer[0]);// <--- THIS LINE 第二个计数器将与第一个计数器 (fullCounter) 大致相同。当此行未注释时,第二个计时器几乎比第一个计数器少两倍。这条线的存在是唯一的区别。

总体: 如果 fprintf 未评论,我的计数器显示更好的 readfile 性能 --> 第二个计数器的时间更短

如果 fprintf 评论我的表现较差 --> 第二个计数器有更多时间

编译器标志:cl -Z7 -nologo -Fmsource.map ../code/source.c

命令日志:

C:\Documents\work\region\testProject\build (master -> origin)
λ source.exe
Opening serial port...OK
Sending bytes...9 bytes written
end flag was received
time: 0.193245
full time: 0.206170
Closing serial port...OK

C:\Documents\work\region\testProject\build (master -> origin)
λ source.exe
Opening serial port...OK
Sending bytes...9 bytes written
end flag was received
time: 0.115640
full time: 0.204010
Closing serial port...OK

我的问题是,为什么会这样?它对我的程序有什么样的影响?

在控制台上打印可能是一项非常耗时的操作,很多时候甚至达到数千个时钟周期。 看看这个 link,其中解释了使用 printf 所消耗的时间。我知道在你的情况下你使用的是 fprintf,但你的目标文件仍然是控制台输出,因此需要中断、上下文切换、在控制台上打印等的整个过程。 我从 link:

中引用了这段代码
int main( void )
{
    int i = 89;

    printf("hello, world %d\n", i);
}

这似乎是一个小而快的代码,但它在 RISC CPU 上需要 6371 个周期。所以想象一下有一个 1MHz 的 RISC CPU,这将需要超过 6 毫秒的时间来执行。

现在想象一下,如果您 运行 您的代码在 OS 的计算机上,则进程和线程之间的切换以及中断例程会引入更多延迟。

fprintf正在执行时,串口不断积累输入数据。下次您尝试阅读时,数据随时可用。如果没有 fprintf,程序必须在 ReadFile 内等待它。因此存在差异。