16
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Kotlin] コルーチンでCPUコアを全て使って並列処理

Last updated at Posted at 2022-08-19

はじめに

Kotlinのコルーチン、私はスレッドに対する明確なメリットを知らず、あまり使ってませんでした。
しかし今回、大量のレコードをなるべく速く処理したいという状況で、コルーチンがとても役に立ったので紹介します。

マルチコアを使い切る

最近のCPUはたいてい複数のコアを持っていますが、シングルスレッドのプログラムでは1つのコアしか使うことができません。
しかし、並列で処理できるタスクなら全てのCPUコアを使って並列処理するのが一番速いです。

全てのCPUコアを使って並列処理するには、コアの数だけスレッドを作り、それらのスレッドを上手く管理して並列に処理をする必要がありますが、マルチスレッドプログラミングは落とし穴が多く、自分で実装すると意外と時間がかかるものです。
しかし、Kotlinのコルーチンを使えばそれを簡単に実現することができます。

コードサンプル

コードから入ります。
以下の数行のコードでCPUコアを全て使って並列処理ができます。

コルーチン並列処理の例
import kotlinx.coroutines.*

fun <T> operateItems(items: Collection<T>, operate: (T) -> Unit) = runBlocking(Dispatchers.Default) {
    items.map {
        async { operate(it) }
    }.awaitAll()
}

簡単にコードの解説をすると、例えば、10万件のレコードを並列処理したい場合、引数itemsに10万件のレコードを渡し、引数operateに各レコードの処理をする関数を渡します。

各レコードについて、async関数で作られたコルーチンで並列処理が行われ、awaitAllで全ての処理が終わるまで待機します。

コルーチンのスレッド管理

コルーチンはDispatherというもので、スレッドの使い方を決めます。
コルーチンは必ずしもマルチスレッドで動くとは限らず、Dispather次第でシングルスレッドで動かすこともできます。

コードサンプルではDispatcherにDispatchers.Defaultを使用していますが、このDispatcherはCPUコアの数だけスレッドを作ってプールし、コルーチンの処理をそれらのスレッドで分散して実行します。
これにより全てのCPUコアを使って並列処理ができます。

Dispatcher.Defaultの説明

コードサンプルの例では、async内に書いたoperate(it)は、CPUコアが空き次第順番に実行されていきます。
例えば、4コアのCPUならoperateがまず4回実行され、いずれかの実行が終わり次第次のoperateが実行され、常に4つのoperateが並行実行されている状態になります。

速度計測

6コアCPUのマシンで上記のコルーチンのコードを実行し、シングルスレッドの処理と速度を比較してみました。
6コアなので上手くいけばコルーチンはシングルスレッドの6倍速になるはずです。

100ミリ秒くらいかかる処理を1000回実行するパターンと、10ミリ秒くらいかかる処理を10000回実行するパターンの2パターンで速度計測しています。

100ミリ秒くらいの処理を1000回実行するコード例
operateItems((1..1000).toList()) {
    processTakes100ms() // Math.pow()を大量実行して100msくらいかかるよう調整した関数
}
シングルスレッド コルーチン
100msの処理 × 1000回 99.4s 17.4s
10msの処理 × 10000回 100.4s 17.5s

シングルスレッドで100秒ほどかかる処理がコルーチンでは17.5秒程度で、シングルスレッドの5.7倍ほどの速度になっています。
6倍には少し届きませんでしたが、十分許容できるオーバーヘッドです。

特に後者はコルーチンを1万個も生成していますが、それでも速度があまり落ちず、軽量であるというコルーチンの強み実感することができました。

まとめ

  • コルーチンのDispathcers.DefaultはCPUコアを全部使ってくれる
  • コルーチンは軽いから大量生産しても大丈夫
16
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?