Top 上へ 目次
Ver.12.3〜12.4 長パス対応の結果で低下していた性能を取り戻したいんだけど、無理かもしれない件
以前実施した長パス対応の結果、表示性能が約1〜2割ほど低下していました。
まぁ、100万ファイルの列挙が2.6秒→3.1秒に増えたからといっても、さほど体感できるレベルではないのですが気持ち悪くて課題になっていました。
というわけで、いくつかの方法を組み合わせて改善していきたいと思います。
まずは、一部の長パス対応の無効化の設定ですね。
こちらは説明要らんでしょう。
表示性能が下がった直接の原因を取り除く選択肢を用意します。
デフォルトは長パス対応「あり」の状態ですが、本気を出すモードを用意するってことです。
2番目に、フィルタ処理の改善です。
「.で始まるファイルを表示しない」とか「ローカルサムネイルキャッシュは表示しない」とか、これって例外的な「フィルタ機能」の一部となってます。
要するに、常時フィルタをONにした状態で使ってるケースが増えてきているんですよ。
フィルタの仕組みはファイル名やらファイル属性を比較するわけで、ITEMIDLISTの状態で判断できません。
各種属性やテキストでファイル名が取得できた後に判断する必要があるので、情報取得用の並列ループとは別に、フィルタ処理用の並列ループが存在していたためです。
というわけで、こいつを1個のループにまとめてやることで、フィルタなしの場合は性能劣化しますが、フィルタありの場合に大幅に性能が上がるというわけです。
大幅っつっても、低下が1%、向上が5%とか、そんな誤差みたいな世界ですが・・・コア数が多い方へ性能改善率をシフトしていくことになります。
3番目は、さり気に大手術なんですが、OpenMPの使用をやめます。
OpenMPとは、マルチコアというモノがわりと初期のころから多用されていた並列ライブラリでして、PPL(MS印の並列処理用API)やら、最近だと並列STL(最近の標準C++)とかが出てきて重要性が減ったとはいえ、その歴史の長さからして最も多様なことが実現可能な、優れたライブラリと言えるでしょう。
ただ残念ながら、Visual Studio 2019では最新版の機能が使えるというわけではなく、ちょっと微妙な世代でサポートが止まってます。
確かこれ、OpenMP 2.0が最初に公開されたのが2003年だったと記憶していますが(うろ覚え)、一昔どころじゃないですね。
SIMD命令も使えるように妙な方向に拡張されているとはいえ、今時2.0で止まってるとか思わなかったです。超期待してたのに。
標準から外れた独自拡張が害悪なのは、Javaなりブラウザなりで痛い目にあったでしょうに・・・
Visual C++上のOpenMPの弱点として、ガイド付き最適化(PGO)が行えないという弱点もあります。
ChromeやFireFoxとかも採用してきた、実行時情報を使ったより高度な最適化ってやつですね。
前に試した時にはピーク性能は全く変わりませんでしたが、幅広い範囲の挙動が7〜8%程度の速度改善してたので期待したいところです。
全自動でコンパイルからリリースパッケージの作成というのはできなくなりますが、手順を変えるだけで性能が向上するなら、やって損はないと思いますし、いろいろ実験してみたいと思います。
OpenMPのもう一つの弱点の、スレッド生成のオーバーヘッドが大きいというのは、すでに影響が大きい部分は既にPPLに置き換えてるので影響なしです。
というわけで、いろいろ比較検討した結果、OpenMPにべったり依存している独自ソートとか、独自検索処理とか、バッサリと放棄しちゃいます。
ソートもマージソートからクイックソートになるので、ファイル名やファイルシステム上の並び順などによって揺らぎ幅が大きくなるでしょうし、演算コストが最悪のケースが発生することもありうるでしょう。
ぶっちゃけピーク性能は低下しますが、環境依存が少なめのSIMD命令を混ぜたりとか色々な選択肢が増えているので、アイデア次第で性能改善できるシーンが多くなりそうです。
AVX2命令の使用版の立場が微妙になる気もしますが・・・今時インラインアセンブラとか無しかなぁ。
というわけで、なるべく性能を落とさない方向で試行錯誤が必要になりそうです。
それにしても速度や性能面に関して、17年前のライブラリ使って、8年前に基本設計したソースコードに、ようやく今の時代のライブラリが追い付いてきたという感がぬぐえません。
レンジ拡張のアルゴリズムはC++20で実装されるようなので次世代には確実に追いつかれますし、その次の世代のC++23では抜き去られます。
今まであったAs/Rの速度的な優位性は、もはや誰でも実現できるってぇ話なので、ちょっと寂しい気もします。
とはいえ、熟練者が時間をかけてギリギリまでチューニングしたレベルのものが、今では誰でもお手軽に使えるようになってきたわけで、技術の進歩には感慨深いものがあります。
ただこれ、教科書に載っている各種ソートをそのまま書いたら、標準ライブラリの足元にも及ばない遅い、実用にならないプログラムになります。
これは「自前で作っても無駄じゃん」となり、アルゴリズムの勉強を怠ることに繋がり、「工数もないから調べるのなしね」が横行することになるかと思います。
性能が良すぎる道具ってのは、教育には良くない気がします。
あとそうそう、インストールテストで「VCTUNTIME140_1.DLLがありません」を検出できるようになります。
これ、64ビット版限定の話だったんですね・・・道理で仮想環境やらタブレット機で再現できないわけです。
今更感が無きにしも非ずですが少しは、インストールトラブルが減らせることを期待しています。
配布書庫の精査もコツコツと進めてますが・・・うん、exeにしても、dllにしても、大杉。
これ作った奴に文句言ってやりたい。
※訂正
改修を進めていくうちに、勘違いしていることに気づきました。
並列STLは、MCSTL(Multi-Core Standard Template Library)をベースにしているそーで、これってOpenMPをガシガシ使用していたと記憶しています。
Visual C++のSTL中身がどうなっているかは深追いしていませんが、VCOMP140.DLLをVCランタイム内からガンガン呼び出しているので、結果的にOpenMPの全廃は不可能となります。
このあたりはWindows updateで告知なく仕様変更されまくってるので詳細は不明ですが、Windowsの同梱アプリケーションもしれっと並列処理の割合いが増えて高性能化しているのかもしれません。