地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【MySQL】innodb_spin_wait_pause_multiplierを調べた

MySQL 8.0.16で追加されたinnodb_spin_wait_pause_multiplierというパラメータについて調べてみた。

dev.mysql.com

スレッドが mutex または rw-lock の取得を待機するときに発生するスピン待機ループ内の PAUSE 命令の数を決定するために使用される乗数値を定義します。

と書いてある。プロセッサーアーキテクチャのPAUSE命令の長さの違いを考慮して、遅延をより細かく調整できるようになったという理解をした。nnodb_spin_wait_pause_multiplier少ない方がX spin roundsが高い傾向なのはpauseの時間が短い分、spin回数が増えるようになる。ただ自宅のMySQLで試してみたがこの理論に当てはまるような結果は得られなかった。mutexを大量に必要とするようなワークロードのテストが必要になりそうでうまいこと再現できていない。

PAUSE命令とは

CPUにおけるPAUSE命令は、特にマルチスレッド環境で使用される、スピンロックのパフォーマンスを向上させるための命令です。マルチスレッドプログラムでは、複数のスレッドが同時に実行されるため、あるリソースへのアクセスを同時に試みることがあります。このとき、リソースが使用中である場合、他のスレッドはそのリソースが解放されるのを待つ必要があります。この待機を効率的に行うために、スピンロックという技術が用いられることがあります。

スピンロックでは、スレッドはアクティブにリソースが利用可能になるのをポーリング(繰り返し確認)します。これにより、コンテキストスイッチのオーバーヘッドを避けることができますが、リソースが長時間にわたって使用されている場合、CPUサイクルを無駄に消費することになります。

PAUSE命令はこの問題を緩和します。PAUSE命令をスピンロックのループ内に挿入することで、CPUに対して他のスレッドやプロセスにより多くのリソースを割り当てる余裕を与えることができます。これにより、スピンロックの待機時間中にCPUのパワー消費を減らし、システムの全体的なパフォーマンスを向上させることができます。

PAUSE命令は、IntelAMDx86アーキテクチャでサポートされています。この命令は、主にアセンブリ言語でプログラミングする際に利用されます。C言語でPAUSE命令を直接使用することはできませんが、インラインアセンブラを使ってC言語のコード内でPAUSE命令を利用することができます。インラインアセンブラは、C言語のコード内でアセンブリ言語の命令を直接記述することを可能にします。以下はサンプルコードです。

#include <stdio.h>

static inline void cpu_pause() {
    __asm__ volatile ("pause");
}

int main() {
    printf("スピンロック前\n");
    cpu_pause(); // ここでPAUSE命令を実行
    printf("スピンロック後\n");
    return 0;
}