Aqoole_Hateenaの技術日記

vulkan+raytraceで色々描いてます

水の表現の挑戦 multi threadで波の計算を高速化した話

描画される波形は前回から変わっていないが、ずっと気になっていたmulti threadで波のポリゴン(頂点のy座標、高さ)の計算を高速化してみた。

std::thread

使うライブラリはstd::threadです。
#include <thread>
でインクルードできます。

使い方

詳しくは
thread - cpprefjp C++日本語リファレンス

【C++】std::thread についての覚え書き - Qiita
をご覧ください。私はあるクラスの中でメンバ関数として呼び出して使用しているので

const uint32_t threadNum = 24;
std::array<std::unique_ptr<std::thread>, threadNum> threads;
for(uint32_t i = 0; i < threadNum; i++)
    threads[i] = std::make_unique<std::thread>(&Class::CalcSeaLevel, this, i, time, threadNum);
for(uint32_t i = 0; i < threadNum; i++)
    threads[i]->join();
for(uint32_t i = 0; i < threadNum; i++)
    threads[i].reset();
void Class::CalcSeaLevel(uint32_t mod, float time, uint32_t threadNum)
{
  uint32_t vertexSize = GetVertexSize();
  for(uint32_t i = 0 + mod; i < vertexSize; i = i + threadNum)
  {
      glm::vec3& pos = mVertices[i].pos;
      if(pos.y > -0.0001f)
          continue;
      pos.y = -1.5 + sin(time * 5.0f - glm::length(pos - glm::vec3(0, pos.y, 0)) * 8.0f) / 16.0f;
  }
}

としています。
上記の2つともクラスのメンバ関数ですが、1つ目の処理で2つ目の関数を呼び出しています。メンバ関数内からメンバ関数をポインタにして呼ぶ場合には

std::thread th(&Class::func, this, argument1, argument2, ...);

となることに注意。
c++ - Start thread with member function - Stack Overflow

処理してほしい関数を渡すだけのイメージなので、シンプルでよいですね。

この処理の後、15fps程度であったのが60fps程度にまで上がっていたので、処理はだいぶ高速化されるようです。