开发者

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;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜