-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ファイル読み込み高速化(行レイアウト化処理のマルチスレッド対応) #1994
ファイル読み込み高速化(行レイアウト化処理のマルチスレッド対応) #1994
Conversation
❌ Build sakura 1.0.4405 failed (commit 8c05729532 by @suconbu) |
|
||
constexpr DWORD userInterfaceInterval = 33; | ||
DWORD prevTime = GetTickCount() + userInterfaceInterval; | ||
ULONGLONG prevTime = GetTickCount64() + userInterfaceInterval; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
対応内容と関係ないですが、C28159 が指摘されていたので修正
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(指摘外) ULONGLONG でなく auto で良いような。
あと「userInterfaceInterval = 33」を仮置きした基準を残すと「より良く」なるような。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
「userInterfaceInterval = 33」を仮置きした基準を残す
userInterfaceInterval
の意味/用途説明があった方が良いんじゃないか?ってことですかね?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
よくよく考えると、prevTime
の初期化で userInterfaceInterval
を加算するのはおかしいような。
1回目は 66ms 間隔、2回目以降は 33ms 間隔となる。意図通りではなさそう。
(直したところで動作の違いは体感できないと思いますが)
eff4747
to
522f22c
Compare
❌ Build sakura 1.0.4406 failed (commit 0544092c52 by @suconbu) |
if(_DoKinsokuSkip(pWork, pfOnLine)){ } | ||
// 禁則処理中ならスキップする @@@ 2002.04.20 MIK | ||
// 禁則関係の設定が全部OFFの場合もスキップ | ||
if(!bKinsokuEnabled || _DoKinsokuSkip(pWork, pfOnLine)){ } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(sonarcloud指摘) 「空の分岐は分かりづらいから、なんで空なのかコメントしようね」的なやつ。
メンテナンス性が上がりそうだけど対応は不要。
個人的には、条件を反転して直後の else とくっ付けるのが好み。
//@@@ 2002.09.22 YAZAKI | ||
color.CheckColorMODE( &pWork->pcColorStrategy, pWork->nPos, pWork->cLineStr ); | ||
if( bCheckColorEnabled ){ | ||
//@@@ 2002.09.22 YAZAKI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(指摘外) こういうコメントを残すかどうか、悩ましいです。
「あると便利か?」を考えるとNoです。
「ないと困るか?」を考えるとNoです。
削ればスッキリしますが、著作権的にもやもやします。
残せば著作権には触れませんが、YAZAKIさんはここ書いてません。
int nLineIndexEnd = nAllLineCount; | ||
CDocLine* pDocLineEnd = nullptr; | ||
for (int i = nWorkerThreadCount; i >= 0; i--) { | ||
const int nLineIndexBegin = (int)((double)nAllLineCount / (nWorkerThreadCount + 1) * i); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(sonarcloud指摘) 必ずしも対応不要。
const int nLineIndexBegin = (int)((double)nAllLineCount / (nWorkerThreadCount + 1) * i); | |
const auto nLineIndexBegin = (int)((double)nAllLineCount / (nWorkerThreadCount + 1) * i); |
|
||
constexpr DWORD userInterfaceInterval = 33; | ||
DWORD prevTime = GetTickCount() + userInterfaceInterval; | ||
ULONGLONG prevTime = GetTickCount64() + userInterfaceInterval; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(指摘外) ULONGLONG でなく auto で良いような。
あと「userInterfaceInterval = 33」を仮置きした基準を残すと「より良く」なるような。
sakura_core/mem/CPoolResource.h
Outdated
@@ -65,6 +65,8 @@ class CPoolResource : public std::pmr::memory_resource | |||
void* do_allocate([[maybe_unused]] std::size_t bytes, | |||
[[maybe_unused]] std::size_t alignment) override | |||
{ | |||
std::lock_guard<std::mutex> lock(mtx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(sonarcloud指摘) 対応必須ではありませんが、メンテナンス性は上がりそう。
std::lock_guard<std::mutex> lock(mtx); | |
std::lock_guard lock(mtx); |
sakura_core/mem/CPoolResource.h
Outdated
@@ -91,6 +93,8 @@ class CPoolResource : public std::pmr::memory_resource | |||
[[maybe_unused]] std::size_t alignment) override | |||
{ | |||
if (p) { | |||
std::lock_guard<std::mutex> lock(mtx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
同上。
if( nListenerCount != 0 && 0 < nLineCount ) { | ||
if( nLineIndex == 0 ){ | ||
const ULONGLONG currTime = GetTickCount64(); | ||
const ULONGLONG diffTime = currTime - prevTime; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(指摘外) prevTime を auto にするならここも。
sakura_core/mem/CPoolResource.h
Outdated
@@ -140,5 +144,7 @@ class CPoolResource : public std::pmr::memory_resource | |||
Node* m_unassignedNode = nullptr; // 未割当領域の先頭 | |||
Node* m_currentBlock = nullptr; // 現在のブロック | |||
Node* m_currentNode = nullptr; // 要素確保処理時に現在のブロックの中から切り出すNodeを指すポインタ、メモリ確保時に未割当領域が無い場合はここを使う | |||
|
|||
std::mutex mtx; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(指摘外) メンバー変数に 「m_」プレフィックスを付けるかどうか、悩ましい。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
気持ち悪いので付けマス
sakura_core/doc/layout/CLayoutMgr.h
Outdated
@@ -292,6 +292,7 @@ class CLayoutMgr : public CProgressSubject | |||
// 2005.11.21 Moca 引用符の色分け情報を引数から除去 | |||
public: | |||
void _DoLayout(bool bBlockingHook); /* 現在の折り返し文字数に合わせて全データのレイアウト情報を再生成します */ | |||
void _DoLayoutSub(CDocLine* pDocLineBegin, CDocLine* pDocLineEnd, int nLineIndexBegin, int nLineCount, std::atomic<bool>* pbCanceled); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
appveyor のビルドエラーは「 atomic が宣言されてない」というものです。
appveyor(vs2017 community edition) 固有のエラーなので、スルーしてよい気もします。
include <atomic>
したら解決する可能性はあります。
✅ Build sakura 1.0.4426 completed (commit 8e655ff590 by @suconbu) |
bd98a09
to
91e4c92
Compare
91e4c92
to
e1a90b4
Compare
❌ Build sakura 1.0.4430 failed (commit a0f45bde03 by @suconbu) |
e1a90b4
to
90f8474
Compare
|
✅ Build sakura 1.0.4431 completed (commit 5ebe925ffd by @suconbu) |
✅ Build sakura 1.0.4432 completed (commit c8e62dbcb8 by @suconbu) |
Acceptありがとうございました。
|
@@ -292,6 +293,7 @@ class CLayoutMgr : public CProgressSubject | |||
// 2005.11.21 Moca 引用符の色分け情報を引数から除去 | |||
public: | |||
void _DoLayout(bool bBlockingHook); /* 現在の折り返し文字数に合わせて全データのレイアウト情報を再生成します */ | |||
void _DoLayoutSub(CDocLine* pDocLineBegin, const CDocLine* pDocLineEnd, int nLineIndexBegin, int nLineCount, std::atomic<bool>* pbCanceled); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
指摘外) std::atomic<bool>* pbCanceled
のポインタ渡しについて。
参照渡し( std::atomic<bool>& isCanceled
)としたほうが可読性、保守性をあげられそうに思いました。
コードベース全体ではポインタ渡しが主流で、[out]
をあえて [out, opt]
にしてるトコ多いので微妙な指摘になりますが。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pbCanceled については、以下の所で bBlockingHook の値によってnull or 有効値を意図的に使い分けるためにポインタ渡しとした次第でした。(代わりにフラグ+参照でも良かったカモ)
https://github.com/sakura-editor/sakura/pull/1994/files#diff-34d5593d67d75e50e7eb3db6eba862a33a37d3e568a87a21d13970626dab8335R389
ポインタ渡しじゃなきゃならない理由が特になければ、参照渡しが良いだろうという意見には同意します。
レビューありがとうございました。マージします。 |
PR対象
カテゴリ
PR の背景
#1988 の第2弾対応です。
ファイル読み込み時の処理で一番時間の掛かっている
CLayoutMgr::_DoLayout
の処理時間の短縮を図ります。CLayoutMgr::_DoLayout
では、前段の処理にて改行単位で分割されたテキストデータを入力として、見た目上の行単位 (レイアウト行) に分割する処理を主にやっていますが、その部分を yoshinrt/SakuraVz の 34d5593d の対応を参考に複数のスレッドで並列実行できるようにします。仕様・動作説明
対応内容:
CLayoutMgr::_DoLayout
のマルチスレッド対応CLayoutMgr::_DoLayout
の実質の処理をCLayoutMgr::_DoLayoutSub
(新規) に移し、それを複数スレッドから実行できるようにします。CLayoutMgr::_MakeOneLine
の高速化ループ処理の手前で色分けや禁則関係の設定有無をあらかじめ確認、フラグに保持しておき、ループ内での不要な関数呼び出しをスキップします。
CPoolResource
クラスの排他制御対応対応「1」により、
CLayoutMgr
クラスが持つ1つのメモリプールを複数スレッドから同時に操作することになるため、CPoolResource
のdo_allocate
,do_deallocate
メソッドに対して std::mutex を使った排他制御を追加します。4スレッドで処理する場合のイメージ:

参考元対応から変えた主な点:
行をまたぐ色分け設定 (
/*...*/
など) のいずれかが有効の時はマルチスレッド処理を無効化有効時はひとつ前の行の色分け状態を連鎖的に考慮する必要があり、色分け区間の途中で処理が分割されると正しく色分けできなくなる懸念があったため、設定有効時は従来通りシングルスレッドで処理させます。
(巨大となりがちなログファイルなどの拡張子に対して、行をまたぐ色分けの設定がされることはまれだろう・・・という想定とします)
(参考元ではマルチスレッド処理するのは一部機能制限があるとする「巨大ファイルモード」の場合に限定)
CLayoutMgr
クラスにおけるメモリプール (CPoolResource
) の使用を継続排他制御を追加したとしてもメモリプールを使った方が直接 new/delete するよりも処理時間が短くなることが確認できたので引き続き使うことにしています。
(参考元では 4f5c0285 にてメモリプールを廃止)
各区間の処理時間 (計測条件などは #1988 を参照):
PR の影響範囲
テスト内容
test.zip 内のファイルを使って以下を確認します。
関連 issue, PR
参考資料