OpenGL GPU 処理時間の計測ユーティリティ | puarts.com
映像・CG・画像処理関連の技術情報、個人作品の創作記録、メモなど
Category

OpenGL GPU 処理時間の計測ユーティリティ

公開日: 2016/03/02 | カテゴリ: OpenGL | タグ:

GL で GPU 時間を計測するためのユーティリティクラスを作ったので載せておきます。

class GpuTimer
{
public:
    GpuTimer()
        : query_back_buffer_(0)
        , query_front_buffer_(1)
    {
    }

    ~GpuTimer() throw()
    {
        DeleteAllQueries();
    }

    void Start(const char* query_id)
    {
        int query_index = GetIndex(query_id);
        if (query_index == -1)
        {
            query_index = static_cast<int>(query_ids_.size());
            AddQuery(query_id);
        }
        glBeginQuery(GL_TIME_ELAPSED, queries_[query_back_buffer_][query_index]);
    }

    void Stop()
    {
        glEndQuery(GL_TIME_ELAPSED);
    }

    void ResetAllQueries()
    {
        for (int query_index = 0, queryCount = GetQueryCount(); query_index < queryCount; ++query_index)
        {
            glBeginQuery(GL_TIME_ELAPSED, queries_[query_back_buffer_][query_index]);
            glEndQuery(GL_TIME_ELAPSED);
        }
    }

    int GetQueryCount() const
    {
        return static_cast<int>(query_ids_.size());
    }

    double GetElapsedMilliseconds(int query_index)
    {
        GLuint64 elapsed_gpu_time;
        glGetQueryObjectui64v(queries_[query_front_buffer_][query_index],
            GL_QUERY_RESULT, &elapsed_gpu_time);

        return elapsed_gpu_time / 1000000.0;
    }

    void SwapQueryBuffers()
    {
        if (query_back_buffer_ == 1)
        {
            query_back_buffer_ = 0;
            query_front_buffer_ = 1;
        }
        else
        {
            query_back_buffer_ = 1;
            query_front_buffer_ = 0;
        }
    }

    const char* GetQueryId(int query_index) const
    {
        return query_ids_[query_index].data();
    }

private:
    int GetIndex(const char* query_id) const
    {
        int query_index = 0;
        for (std::vector<std::string>::const_iterator iter = query_ids_.begin(), end = query_ids_.end();
            iter != end; ++iter, ++query_index)
        {
            const std::string* id = &*iter;
            if (*id == query_id)
            {
                return query_index;
            }
        }

        return -1;
    }

    void AddQuery(const char* query_id)
    {
        int last_index = static_cast<int>(query_ids_.size());
        query_ids_.push_back(query_id);
        queries_[query_front_buffer_].push_back(0);
        queries_[query_back_buffer_].push_back(0);
        glGenQueries(1, &queries_[query_front_buffer_][last_index]);
        glGenQueries(1, &queries_[query_back_buffer_][last_index]);
    }

    void DeleteAllQueries()
    {
        GLsizei query_count = static_cast<GLsizei>(queries_[query_front_buffer_].size());
        glDeleteQueries(query_count, queries_[query_front_buffer_].data());
        glDeleteQueries(query_count, queries_[query_back_buffer_].data());
        queries_[query_front_buffer_].clear();
        queries_[query_back_buffer_].clear();
    }

private:
    static const int QUERY_BUFFER_COUNT = 2;
    std::vector<unsigned int> queries_[QUERY_BUFFER_COUNT];
    unsigned int query_back_buffer_;
    unsigned int query_front_buffer_;
    std::vector<std::string> query_ids_;
};

class ScopedGpuTimeLogger
{
public:
    ScopedGpuTimeLogger(GpuTimer& timer, const char* query_id)
        : timer_(&timer)
    {
        timer_->Start(query_id);
    }
    ~ScopedGpuTimeLogger()
    {
        timer_->Stop();
    }

private:
    GpuTimer* timer_;
};


使用例

GpuTimer gpu_timer;

{
    ScopedGpuTimeLogger scoped_logger(gpu_timer, "GPU time 0");
    // 計測したい GPU コマンド
}

{
    ScopedGpuTimeLogger scoped_logger(gpu_timer, "GPU time 1");
    // 計測したい GPU コマンド
}

for (int query_index = 0, query_count = gpu_timer.GetQueryCount(); query_index < query_count; ++query_index)
{
    double elapsed_ms = gpu_timer.GetElapsedMilliseconds(query_index);
    printf("%s: %f ms\n", gpu_timer.GetQueryId(query_index), elapsed_ms);
}

gpu_timer.SwapQueryBuffers();

glutSwapBuffers();

参考サイト
http://www.lighthouse3d.com/tutorials/opengl-timer-query/


  このエントリーをはてなブックマークに追加  

にほんブログ村 デザインブログ グラフィックアートへ
Links

参考になりそうなブログやサイトを見つけたら勝手にリンクを貼らせてもらっています。
リンク削除を希望の場合はお手数ですがメールにてご一報下さい。
Ke-Sen Huang's Home Page        Disney Research        VIDEO COPILOT        AbandonedArt.org
ryoji ikeda        チームラボ        トルク with AR三兄弟        DAITO MANABE

Copyright(C)2006-2017 wsp All Rights Reserved