Cudaプログラムの実行時間測定

Cuda入門に出てきた関数をクラスにまとめたので、コピペ用に。

Code Snippet 1: cudaTimer.h

#ifndef CUDATIMER_H
#define CUDATIMER_H

#include <iostream>
#include <stdlib.h>

#include "cuda_runtime.h"

// cudaのエラー検出用マクロ
#define EXIT_IF_FAIL(call)                                                     \
  do {                                                                         \
    (call);                                                                    \
    cudaError_t err = cudaGetLastError();                                      \
    if (err != cudaSuccess) {                                                  \
      std::cout << "error in file " << __FILE__ << " line at " << __LINE__     \
                << ": " << cudaGetErrorString(err) << std::endl;               \
      exit(1);                                                                 \
    }                                                                          \
  } while (0)

class CudaTimer {
private:
  cudaEvent_t start, end;

public:
  CudaTimer() {
    EXIT_IF_FAIL(cudaEventCreate(&start));
    EXIT_IF_FAIL(cudaEventCreate(&end));
  }
  ~CudaTimer() {
    EXIT_IF_FAIL(cudaEventDestroy(start));
    EXIT_IF_FAIL(cudaEventDestroy(end));
  }
  // 計測開始
  void begin() {
    EXIT_IF_FAIL(cudaEventRecord(start));
  }
  // 計測終了
  void stop() {
    EXIT_IF_FAIL(cudaEventRecord(end));
  }
  // 測定結果を出力
  void report() {
    // イベントendが終わるまで待つ
    EXIT_IF_FAIL(cudaEventSynchronize(end));
    float elapsed;
    EXIT_IF_FAIL(cudaEventElapsedTime(&elapsed, start, end));
    printf("elapsed: %f ms\n", elapsed);
  }
  void stop_and_report() {
    stop();
    report();
  }
};

#endif /* CUDATIMER_H */

上のプログラムを cudaTimer.h と保存すると、以下のように使える。

Code Snippet 2: main.cu

#include <cuda_runtime.h>
#include <stdio.h>
#include <unistd.h>

#include "cudaTimer.h"

// 何もしない
__global__ void empty() {}

int main() {
    CudaTimer timer;
    timer.begin();
    // 何もしない関数を呼ぶとどれくらい時間がかかるのだろう?
    empty<<<1024, 1024>>>();
    timer.stop_and_report();

  return 0;
}

上のプログラムを main.cu という名前で保存して以下のように実行すれば実行の時間を計測できる。

$ nvcc -run main.cu
elapsed: 0.017344 ms

c++のことをよく知らないのでクラスの作り方に自信がないが、今のところ特に問題なく使えている。