Intel(R) Core(TM)2Duo T8100 @2.10GHz 2.10GHz
RAM 4.00GB
GCC(MinGW) 4.8.1
usleep関数を用いたFPS制御のプログラムを書いたのですが、なぜか指定したFPS+1に近い値が測定されます。
1FPSや10FPSに設定しても+1になったので、誤差ではないと思います。
FPS測定(calcFPS関数)とFPS制御(adjustFPS関数)のどっちにバグがあるかもわからないのですが、
どうしてFPSが1多くなってしまうのでしょうか?
よろしくお願いします。
このルーチンはOpenGLを用いたプログラムに組み込んでいるのですが、
OpenGLを使わないプログラムでも再現したので、それを載せます。
fat.cpp
#include <sys/time.h>
#include <unistd.h>
#include <cstdio>
static int fpslimit=60;
long long getNowTimeUs(void) {
timeval tv={0,0};
gettimeofday(&tv,NULL);
return (long long)(tv.tv_sec*1000000+tv.tv_usec);
}
double calcFPS(bool& fpsUpdated) {
static double fps=0;
static long long prevTime=getNowTimeUs();
static int frameCount=0;
long long nowTime=getNowTimeUs();
frameCount++;
if(prevTime+1000000<=nowTime) {
fps=frameCount*1000000.0/(nowTime-prevTime);
prevTime=nowTime;
frameCount=0;
fpsUpdated=true;
} else {
fpsUpdated=false;
}
return fps;
}
void adjustFPS(void) {
static long long prevTime=getNowTimeUs();
static int frameCount=0;
long long nowTime;
long long timeDiff;
if(fpslimit<=0)return;
nowTime=getNowTimeUs();
frameCount++;
timeDiff=1000000*frameCount/fpslimit-(nowTime-prevTime);
if(timeDiff>0)usleep(timeDiff);
if(frameCount>=fpslimit) {
prevTime=nowTime;
frameCount=0;
}
}
int main(int argc,char* argv[]) {
if(argc>=2)sscanf(argv[1],"%d",&fpslimit);
printf("fpslimit=%d\n",fpslimit);
for(;;) {
double fps;
bool fpsUpdated=false;
fps=calcFPS(fpsUpdated);
if(fpsUpdated) {
printf("%.2ffps\n",fps);
}
adjustFPS();
for(volatile int i=0;i<100000;i++); // 適当な負荷をかける
}
return 0;
}
オフトピック
ここでのfatは「FPS Adjust Test」の略です。