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
内等待它。因此存在差异。
我有两个计数器:
#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
内等待它。因此存在差异。