Am I calculating my FPS correctly?
So I was wondering if I'm calculating my FPS correctly:
Uint32 delayFrom(float startTime, float endTime){
return(endTime - startTime );
}
int main(){
int numFrames = 0;
Uint32 startTime = SDL_GetTicks();
while(!done){
frameTime = 0;
开发者_如何学Go float fps = ( numFrames/(float)(SDL_GetTicks() - startTime) )*1000;
cout << fps << endl;
SDL_Delay(delayFrom(frameTime, 1/60));
++numFrames;
}
}
int main() {
int numFrames = 0;
Uint32 startTime = SDL_GetTicks();
while (!done) {
++numFrames;
Uint32 elapsedMS = SDL_GetTicks() - startTime; // Time since start of loop
if (elapsedMS) { // Skip this the first frame
double elapsedSeconds = elapsedMS / 1000.0; // Convert to seconds
double fps = numFrames / elapsedSeconds; // FPS is Frames / Seconds
cout << fps << endl;
}
SDL_Delay(1.0/60.0); // Use floating point division, not integer
}
}
The implementation of concurent limited queue with FPS counter:
template<typename T, typename Container=std::deque<T>, typename Compare = std::less<typename Container::value_type>>
class ConcurentLimitedQueue : protected std::priority_queue<T, Container, Compare> {
using clock_t = std::chrono::system_clock;
using timepoin_t = std::chrono::time_point<clock_t>;
using duration_t = std::chrono::milliseconds;
private:
const double ALPHA = 0.1;
public:
explicit ConcurentLimitedQueue(size_t upperLimit, size_t lowerLimit = 0) : upperLimit_{upperLimit},
lowerLimit_{lowerLimit},
stop_{false},
lastTime_{clock_t::now()},
counter_{0},
fps_{0.0} {}
bool enqueue(const T &entry) {
std::unique_lock<std::mutex> lock(mutex_);
while (!stop_ && std::priority_queue<T, Container, Compare>::size() >= upperLimit_) {
removedItemCondition_.wait(lock);
}
if (stop_) {
return false;
}
std::priority_queue<T, Container, Compare>::emplace(entry);
updateFPS();
newItemCondition_.notify_one();
return true;
}
bool enqueue(T &&item) {
std::unique_lock<std::mutex> lock(mutex_);
while (!stop_ && this->c.size() >= upperLimit_) {
removedItemCondition_.wait(lock);
}
if (stop_) {
return false;
}
std::priority_queue<T, Container, Compare>::emplace(std::move(item));
updateFPS();
newItemCondition_.notify_one();
return true;
}
bool dequeue(T &item) {
std::unique_lock<std::mutex> lock(mutex_);
while (!stop_ && std::priority_queue<T, Container, Compare>::size() <= lowerLimit_) {
newItemCondition_.wait(lock);
}
if (stop_) {
return false;
}
item = std::priority_queue<T, Container, Compare>::top();
std::priority_queue<T, Container, Compare>::pop();
removedItemCondition_.notify_one();
return true;
}
T dequeue() {
std::unique_lock<std::mutex> lock(mutex_);
while (!stop_ && std::priority_queue<T, Container, Compare>::size() <= lowerLimit_) {
newItemCondition_.wait(lock);
}
if (stop_) {
return {};
}
auto item{std::priority_queue<T, Container, Compare>::top()};
std::priority_queue<T, Container, Compare>::pop();
removedItemCondition_.notify_one();
return item;
}
T top() {
std::unique_lock<std::mutex> lock(mutex_);
while (!stop_ && std::priority_queue<T, Container, Compare>::empty()) {
newItemCondition_.wait(lock);
}
if (stop_) {
return {};
}
return std::priority_queue<T, Container, Compare>::top();
}
float fps() {
return static_cast<float>(fps_);
}
void stop() {
std::unique_lock<std::mutex> lock(mutex_);
stop_ = true;
newItemCondition_.notify_all();
removedItemCondition_.notify_all();
}
void clear() {
std::unique_lock<std::mutex> lock(mutex_);
while (!std::priority_queue<T, Container, Compare>::empty()) {
std::priority_queue<T, Container, Compare>::pop();
}
stop_ = false;
counter_ = 0;
fps_ = 0.0;
}
bool empty() {
std::unique_lock<std::mutex> lock(mutex_);
return std::priority_queue<T, Container, Compare>::empty();
}
protected:
void updateFPS() {
counter_++;
const auto now{clock_t::now()};
const auto delta{now - lastTime_};
if (counter_ && delta > duration_t(1000)) {
const double fps{(1000.0 * counter_) / std::chrono::duration_cast<duration_t>(delta).count()};
fps_ = (ALPHA * fps) + (1.0 - ALPHA) * fps_;
counter_ = 0;
lastTime_ = now;
}
}
private:
size_t upperLimit_;
size_t lowerLimit_;
std::atomic_bool stop_;
timepoin_t lastTime_;
size_t counter_;
std::atomic<double> fps_;
std::mutex mutex_;
std::condition_variable newItemCondition_;
std::condition_variable removedItemCondition_;
};
frameTime never gets assigned anything other than 0. Presumably that's an error.
cout
could be slow so to get more precise value you need to split the time measurement and the output the result.
int main(){
int numFrames = 0;
long totalTime = 0;
while(!done){
// measure time
const Uint32 startTime = SDL_GetTicks();
SDL_Delay( 1.0f/60.0f );
const Uint32 endTime = SDL_GetTicks();
// calculate result
totalTime += endTime - startTime;
++numFrames;
float fps = numFrames / (totalTime / 1000.0);
cout << fps << endl;
}
}
精彩评论