我计算的 FPS 正确吗?

发布于 2024-10-31 14:13:45 字数 448 浏览 4 评论 0原文

所以我想知道我是否正确计算了 FPS:

Uint32 delayFrom(float startTime, float endTime){
    return(endTime - startTime );
}


int main(){
    int numFrames = 0;
    Uint32 startTime = SDL_GetTicks();
    while(!done){
        frameTime = 0;
        float fps = ( numFrames/(float)(SDL_GetTicks() - startTime) )*1000;
        cout << fps << endl;
        SDL_Delay(delayFrom(frameTime, 1/60));
        ++numFrames;
    }
}

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;
        float fps = ( numFrames/(float)(SDL_GetTicks() - startTime) )*1000;
        cout << fps << endl;
        SDL_Delay(delayFrom(frameTime, 1/60));
        ++numFrames;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

没企图 2024-11-07 14:13:45
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
  }
}
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
  }
}
许仙没带伞 2024-11-07 14:13:45

带FPS计数器的并发受限队列的实现:

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

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_;
};
盗琴音 2024-11-07 14:13:45

frameTime 永远不会被分配除 0 以外的任何值。大概这是一个错误。

frameTime never gets assigned anything other than 0. Presumably that's an error.

半葬歌 2024-11-07 14:13:45

cout 可能会很慢,因此要获得更精确的值,您需要拆分时间测量并输出结果。

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

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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文