Upgrade to Pro — share decks privately, control downloads, hide ads and more …

BCMathを高速化した一部始終をC言語でガチ目に解説する / BCMath perfor...

BCMathを高速化した一部始終をC言語でガチ目に解説する / BCMath performance improvement explanation

PHP 8.4では、BCMathにオブジェクトAPIの追加と処理の高速化という大きなアップデートが行われました。このトークでは、BCMathの処理速度向上について詳しく解説します。まず、従来のBCMathが「なぜ遅かったのか」を明らかにし、その問題点を具体的に説明します。その後、新しいコードの改善点や実装方法について詳しく説明します。普段PHPを使用する際には見えない部分であるメモリ管理やCPUの処理が主なテーマとなります。これにより、BCMathの内部動作への理解を深めていただける内容となっています。

(PHPerKaigi 2025)

Saki Takamachi

March 22, 2025
Tweet

More Decks by Saki Takamachi

Other Decks in Technology

Transcript

  1. BCMathの中身を解説 bc_struct構造体 n_len 整数部の桁数 n_scale 小数部の桁数 *n_value 値のchar配列へのポインタ 値は、小数点無しで整数部、小数 部が連続して入っている

    ポインタの位置は先頭(最も大き い桁の位置) n_ref 参照数 メモリ解放の判断に使用する n_sign 符号(PLUS, MINUSのenum)
  2. 誰がどのように高速化に取り組んだのか Niels Dossche わたし • 変換と解析に時間がかかりすぎてい ることを突き止めた • 変換と解析の効率をあげることで高 速化

    • メモリ確保の回数を減らし、可能な らヒープではなくスタック領域を使 用するようにした • 四則演算はどれも1桁ずつの計算な ので、並列計算を試みた • 加算と減算はBCD特有の方法で並列 計算し、乗算と除算は数値をベクト ル化して並列計算を行うようにした ※Nielsが計算ロジック、私が解析などをすることもありました
  3. 文字列をBCDへ変換する 解析と同じような 並列処理を導入 残り文字数が 16文字以上 => 128-bit ベクトルで並列 8文字以上 =>

    64-bitの整数型で並列 それ未満 => 通常のループ処理 なぜ引き算ではなくxor? => BCDから文字列へ戻す時には逆に足すことができ、コードを流用できるため
  4. 計算処理 - 割り算 (4/5) なぜ上位9桁を使うと、足し戻しが1回で済むの? (10^N)進数の多倍長除算では N + 1桁の除数上位桁を使って商予測すると、商予測の誤差は最大で1である という法則があるからです。商予測の誤差が1以内なら、当然足し戻しも1回になります。

    例: 10000進数なら、これは10^4なので、4 + 1で5桁の除数上位桁を使用すればOKです。 正直に言うと、この法則が割り算高速化の全てだったと言っても過言ではないかもしれません。
  5. 計算処理 - 割り算 (5/5) コメントで証明を書いた この法則が既に世の中で発見されて名前がついているのかは知らな いのですが、私はこれを自力で見つけて証明しました。 私とレビュアーだけ把握していればいいものではないので、BCMath ライブラリのdiv.cというファイルに、コメントで証明を残してあり ます。

    85行、大体(英字で)4000文字くらいです。 もし「php-src内、コメント長い選手権」があったら優勝候補です。 証明を書くのも、証明をレビューしてもらうのも、証明関係は何も かもに時間がかかりました。 (最終的に2ヶ月くらいかかったかも...) 何はともあれ、この法則を証明できたことにより、割り算でも1億進 数で効率的な計算ができるようになりました。
  6. 今後のBCMathで考えていること(いたこと) • データを最初からBCDではなくBC_VECTORで持ったらどうか? => 遅くなったのでやめた • 掛け算と割り算で、小さな桁数の時はもっとスタック領域を使う(あとPR作るだけ) • 余りの計算(mod)がまだ効率悪いので改善する(あとPR作るだけ) •

    (オブジェクト使用時)一時的にしか出てこないデータにスタック領域使いたい • BC_VECTOR => BCDへの変換時、少ない桁でもLUTを使いたい • 「1.3E3」のような、科学記法の小数値に対応するかもしれない(要議論 & RFC?)