09/10/02 13:52:10
>>135
それはメモリバリアの問題であって、movかCASかは関係ない。
mov命令がreleaseメモリバリア効果を持っていればそれで十分だし、
逆に>110で挙げたようなメモリバリア無しCAS命令では不十分。
137: ◆0uxK91AxII
09/10/02 13:54:13
>>135
それはspinlockを使う側が考慮する問題であって、
作る側は無視して良い。
138: ◆0uxK91AxII
09/10/02 13:59:49
W2kSP4, Athlon 64 X2 3800+, VC6SP6+PP5, 最適化無し
50239 clocks at CriticalSection
49180 clocks at CAS
21132 clocks at CAS(lockプリフィックス無し)
32103 clocks at CAS(movでunlock)
139:デフォルトの名無しさん
09/10/02 14:24:08
>>136
それがメモリバリアの問題だっていう、そんなことわかってるよ。
そして、「一般的なmov」はメモリバリアの機能など持っていない事
さらに、「(次に書く)このスレで"一般に"用いられるCASという用語」はメモリバリアを持っているもね。
もちろん、CASというのがメモリバリアとは直接は関係ないってことだって充分知ってるよ。
(そうでなければ、lockなしのcmpxchgなんてもの出すわけ無いだろ)
だけどこのスレで一般的にCASと言ったら
「アトミック操作で用いる事が可能なCAS」のことが普通だろうに。
140:デフォルトの名無しさん
09/10/02 14:28:11
「一般的なmov」つまり、普通のロード/ストア操作はメモリバリアを持っていないのだから
普通のスピンロックの実装では、アンロック処理に
movではなくメモリバリアを持ったTASやCASを使う。
(それらはロック獲得処理の段階で存在が示されている)
だから「普通はmovでアンロック」などということは有りえない。
141:デフォルトの名無しさん
09/10/02 14:37:59
>>140は「教科書では」ね。
142:デフォルトの名無しさん
09/10/02 14:53:16
Windows Vista 64bit SP1, Core2DuoE6750, Microsoft Visual Studio 2008(VC Version 9.0.21022.8 RTM)
/O2 /Ob2 /Oi /Ot (実行速度で最適化、インライン関数は展開可能な関数すべて展開)
101192 clocks at CriticalSection
67904 clocks at CAS
20424 clocks at CAS(lockプリフィックス無し)
88688 clocks at CAS(movでunlock)
/Od /Ob1(最適化なし、インライン関数は展開しない)
108568 clocks at CriticalSection
99976 clocks at CAS
24184 clocks at CAS(lockプリフィックス無し)
65280 clocks at CAS(movでunlock)
>>130の結果が謎すぎる
143:デフォルトの名無しさん
09/10/02 15:17:56
>>139
アトミック性とメモリバリアは別の概念だぞ。
CASがアトミックなのは当たり前であり、俺もそんなことに
文句をつけているわけじゃない。
x86におけるlockプレフィックスのないcmpxchgは
SMP環境ではアトミック性が保証されないから
(正しい意味での)CASとは言えない。
でも、>110で挙げたのは「アトミック性は保証されているが
メモリバリア効果を持たないCAS」だ。
CASとは「あるメモリ位置に対する内容の取得・比較から代入までが
アトミックに行える操作」であり、メモリバリア効果、つまり
「前後の命令との間でリオーダーを行わないという保証」は必須ではないと
俺は言っている。
# 実際に、C++0xのatomicライブラリではそのように定義されているし。
「普通のロード/ストア命令はメモリバリアを持たない」と言うのなら、
メモリバリアを持つロード/ストア命令を定義して、それを使えばいい。
何故わざわざCASやTASのような複雑な操作を持ち出す必要がある?
ちなみに、x86のmov命令は(初期のバグ持ちプロセッサを除いて)
デフォルトでreleaseメモリバリア効果を持っているぞ。
144:デフォルトの名無しさん
09/10/02 15:36:13
はいはいごめんよ。
全部俺が悪かったよ。
145:デフォルトの名無しさん
09/10/03 09:36:48
URLリンク(d.hatena.ne.jp)
ここが勉強になった。
146:デフォルトの名無しさん
09/10/03 10:16:52
ちらっと見ただけなんだけど、「volatile つけた変数に排他性は無いよ」
ってことをグダグダ言ってるみたいだけど、そんなの当たり前では?
都市伝説もくそもねーよ
147:デフォルトの名無しさん
09/10/03 11:06:13
acquire/releaseバリヤって、
「そのスレッドでのメモリアクセスについて」限定?
↑のスライドだと前後の命令を・・・となってるけど
148:デフォルトの名無しさん
09/10/03 11:36:54
当たり前よ
っつかどういう意味で聞いてる?
149:デフォルトの名無しさん
09/10/03 11:37:10
菊池バリヤー!
150:デフォルトの名無しさん
09/10/03 16:40:11
「バリア」って概念には
「メモリアクセスがコーダーが記述した”順”に実行されることが
保証される」っていう以上のものは含まれていない(例えばインク
リメント操作がアトミックになることまでは保証されない)と認識し
ているのですが。当たってます?
ネットに散らばっている情報にはブレがあると思えるし、正直、
勉強不足ではっきりと分からないところがあるので質問します。
151:デフォルトの名無しさん
09/10/03 18:09:38
>>150
それで正しい。
ちなみに、マルチスレッドの世界には「バリア同期」っていう全然別のものもあるので、
メモリバリアのことは「メモリフェンス」と呼ぶようにした方がいい。
152:デフォルトの名無しさん
09/10/03 19:15:56
>>151
ありがとうございます。頭の中がすっきりしました。
153: ◆0uxK91AxII
09/10/03 21:22:33
どうでも良い事だけど。
spinlockを奪い合った場合、
先に取ろうとした方が取れず、
後から取ろうとした方が取れたとしても、
動作としては正しいんだよね。
154:デフォルトの名無しさん
09/10/03 21:37:43
spinlockはアンフェアだからそれで正しいね。
155:デフォルトの名無しさん
09/10/03 22:29:57
>spinlockはアンフェアだからそれで正しいね。
それは答えになってるのか??
156:デフォルトの名無しさん
09/10/03 23:21:32
間違いではない=正しい
という論理がわからないのか?
どうしょうーもねーな
157:デフォルトの名無しさん
09/10/03 23:32:43
正しいのか?って言ってんじゃなくて
答えになってるのか?
って言ってんだけど。
158:デフォルトの名無しさん
09/10/04 00:51:01
答えにはなっているように見える。「正しいのか?」という問いに「正しい」と答えている。
その答えが正しいのかどうかは別の話。
159:デフォルトの名無しさん
09/10/04 03:29:21
URLリンク(ja.wikipedia.org)
160:デフォルトの名無しさん
09/10/05 13:09:01
>>155
説明になっているかどうかはともかく
答えにはなっていると思うんだが。
161:デフォルトの名無しさん
09/10/13 02:20:13
火元の人
やり方が理解できない質問者
俺に分からないならこのスレにも理解できる奴いないんじゃね、とか思っていて、
それが態度にも滲み出ている
煽る人
分かってるつもりだけど分かってないで煽り続ける
こいつを見た火元は「やっぱり分かってる奴いないんじゃないか」と思いこむ
住人タイプA
一目で分かるがお前の態度が気に入らないしコード示すのマンドクセ
つーかこの説明で分かれボユゲ
住人タイプB
みんな何言ってんだかわかんね
ちょっと違うけどこのパターンに似てる
162:デフォルトの名無しさん
09/10/14 09:48:32
posix準拠のオーソドックスなやり方しかしない俺にはこのスレは不要なようだ
おまえら何言ってるかわかんねぇーしw
163:デフォルトの名無しさん
09/10/14 10:36:30
>>162
自分からPOSIXスレッドとかに関連したネタをふればいいんじゃないかな?
まあ正直なところ、ここは相談室スレなんだから、あまりにもハードウェア寄りな専門知識が
必要な話題については、できれば「並列化について語る」スレで熱く語ってくれって感じはしてる。
あっちはハード(マルチプロセッサ/マルチコア)全然オケーなスレなんだから。
164:デフォルトの名無しさん
09/10/14 13:09:43
単に自分の付いていけないレベルの話題を締め出したいだけに見える
165:デフォルトの名無しさん
09/10/14 13:35:03
ということにしたいだけにも見える
166:デフォルトの名無しさん
09/10/14 21:17:55
つーか俺はposix準拠な世界で生きてきたので。
おまえらよくposix非準拠な話題で盛り上がれるなーw
167:デフォルトの名無しさん
09/10/14 22:48:54
>>166
CASやメモリバリアなどはpthreadライブラリの実装者にとっても
必須の知識だよ。
168:デフォルトの名無しさん
09/10/14 23:10:22
>>167
利用者にとっては?
169:デフォルトの名無しさん
09/10/15 03:21:14
POSIX厨としか言いようがない
170:デフォルトの名無しさん
09/10/15 08:47:16
>>169
POSIX使うのが普通じゃないの?
171:デフォルトの名無しさん
09/10/15 13:13:35
pthreadにはアトミック操作が定義されてないから、
単なるカウンタのインクリメントでも
いちいちロックしなきゃならんのが嫌だ。
172:デフォルトの名無しさん
09/10/16 00:37:47
なんでPOSIXで厨なんだよ(´・ω・`)
173:デフォルトの名無しさん
09/10/16 02:28:34
POSIXスレッド以外の話題ってだけで叩くなら完全に厨だろ
174:デフォルトの名無しさん
09/10/16 06:51:32
他人を厨と決めつける人が厨に見える
175:デフォルトの名無しさん
09/10/16 08:03:36
何でも鸚鵡返しすれば反論になると思ってるだろ
176:デフォルトの名無しさん
09/10/16 08:04:58
baka
177:デフォルトの名無しさん
09/10/16 08:09:28
pthread地獄 part 2
スレリンク(unix板)
ここへ行けばいいのに
178:デフォルトの名無しさん
09/10/17 03:19:26
/\ ┌┐ ┌┐ ___ ___
/ __ \ /\ ..||.. /\ || ___ \\ \
/ / .\ \ \ \ .||. / / ┌─┘└─、\\  ̄  ̄
/ / .\ \ \/ .||. \/ └─┐┌─ 、| |__|
/ / ┌─┐.\ \ ┌──┘└──┐ .|| ||
..\/ └┐┌┘ .\/ └──┐┌──┘ / / ||
┌┘└┐ /\ .||. /\ / / / /
└┐┌┘ / / .||. \ \ / / / /
┌─┘└─┐ \/ ..||.. \/ \/ / /
└──┘ └┘ \/
....、
....................--------、, i~゙7 r‐ッ !゙゙.! ! !
: !――;;;;;;''''''''ゝ ,,ノ゛ ._ / ./ .,! .,! ! ! .,..............! ヽ..........-、
| |./ / .l、,`''-./ ./ ! ! | | ―ーッ .iー''''''''i |
| l'-‐゛ `゙ッ .ゝ、 .| | | ,! ./ ./ ! !
../ .,! /.,r'"\,/ .!ー′ ./ .,! . / ./ | │
.,./ ./ ,..‐" / . / / ./../ ./ .l゙
.r'"./ ゝ/゛ : ,,-'゛./ .〈 / .'|,゙,゙,,,, "
.`゛ ゙'''"
179:デフォルトの名無しさん
09/10/20 15:39:31
その “全米” はグアム島を含むのでしょうか。
180:デフォルトの名無しさん
09/10/20 19:08:01
グアム、どうなんだろ。州に昇格すればいいのに。まあ、しないだろうけど。
181:デフォルトの名無しさん
09/11/03 00:02:53
スレッドを終了させるときは_endthreadexじゃなく
そのままreturnでもいいのか?スタックの開放されない?
182: ◆0uxK91AxII
09/11/03 00:28:01
良い。
mallocで取ってきた領域をfreeしなくて良いのと同じくらいに。
スタックとやらは、_endthreadexとは無関係。
183:デフォルトの名無しさん
09/11/03 00:59:57
freeしろよ
184:デフォルトの名無しさん
09/11/03 01:16:04
スレッドに強くないのに書き込んでみる。
URLリンク(msdn.microsoft.com)(VS.80).aspx
>ただし _endthread または _endthreadex は、_beginthread や _beginthreadex の
>パラメータとして渡されたルーチンからスレッドが戻ると自動的に呼び出されます。
ってことで、returnすれば問題ないかと。
どちらかというと
>_endthread と _endthreadex によって、C++ デストラクタはスレッドで保留状態になり、呼び出されません
なので、呼ばないほうが好ましいような。
185: ◆0uxK91AxII
09/11/03 01:52:01
182は無かった事にしてください。
んゆ。
186:184
09/11/03 14:42:55
スレッドに強い人に補強して欲しいのだけど、それとも184の認識で問題なし?
187: ◆0uxK91AxII
09/11/03 17:34:11
Microsoft Visual Studio\VC98\CRT\SRC\THREADEX.C
んゆ。
188:デフォルトの名無しさん
09/11/03 17:55:09
問題なし
189:デフォルトの名無しさん
09/11/03 22:08:15
スレッド識別子って何なんだ?
何に使うの?
190:デフォルトの名無しさん
09/11/03 22:25:48
殺したり、止めたり。
191:デフォルトの名無しさん
09/11/04 21:43:06
他スレッドの変数の中身知ることってできないかな?
192:デフォルトの名無しさん
09/11/04 21:55:11
メモリ空間は共有しているので、アドレスがわかれば普通に参照できる。
193:デフォルトの名無しさん
09/11/05 12:32:06
win32のインターロックをクリティカルセクションと
同じように使ったら早くて驚いた。
両者の内部的な違い・利点・欠点てなんですかね?
194:デフォルトの名無しさん
09/11/05 14:06:45
そもそも用途が違うんじゃない?
インターロックは変数1個ぶんの更新しかできないでしょ?
インターロックを使ってクリティカルセクションと同様のものを作ることはできるだろうし、
クリティカルセクションを使ってインターロックと同様のものを作ることもできるだろうけど、
そういう話?
195:デフォルトの名無しさん
09/11/05 14:31:15
インターロック一発で出来ることならインターロックで。
196:デフォルトの名無しさん
09/11/05 14:54:32
win32のクリティカルセクションは衝突しなければインターロックと同じくらい早いんだなこれが
197:デフォルトの名無しさん
09/11/05 16:01:33
いや倍くらいは遅いだろう。
198:デフォルトの名無しさん
09/11/05 16:15:02
んだ。インターロックで済むならそれが数倍早い。
199:193
09/11/05 19:29:23
今以下のクラスでクリティカルセクションと同じように扱ってテストしてるんだ。
class InterLock
{
private:
LONG m_Flag;
public:
void Enter()
{
while(InterlockedCompareExchange(&m_Flag,1,0)) Sleep(0);
}
void Leave()
{
InterlockedCompareExchange(&m_Flag,0,1);
}
public:
InterLock()
{
m_Flag = 0;
}
virtual ~InterLock()
{
}
};
200:193
09/11/05 19:30:08
こっちはクリティカルセクション晩
class CriticalSection
{
private:
CRITICAL_SECTION cs;
public:
void Enter()
{
EnterCriticalSection(&cs);
}
void Leave()
{
LeaveCriticalSection(&cs);
}
public:
CriticalSection()
{
InitializeCriticalSection(&cs);
}
virtual ~CriticalSection()
{
DeleteCriticalSection(&cs);
}
};
201:193
09/11/05 19:43:57
//グローバル変数
ロッククラス g_Lock;
int g_i = 0;
// 三つのスレッドで以下を走らせる
void Run()
{
for(int i=0; i<10000000; i++)
{
g_Lock.Enter();
g_i++;
g_Lock.Leave();
}
}
int main()
{
//3つのスレッドでRun()を走らせ、スレッド終了まで待機
(...省略)
cout << g_i << endl;
cout << time.result() << endl;
return 0;
}
結果
クリティカルセクション 35秒 g_i = 30000000
インターロック 5.5秒 g_i = 30000000
ロッククラス無し 0.16秒 g_i = 21203536(整合性無し)
環境 OS:win xp CPU:core2duo1.8G メモリ:3G
202:デフォルトの名無しさん
09/11/05 20:42:07
ソースまともに見てないけど、CSがもしインライン化されないなら性能的には勝てない
だろうしなぁ
まぁ、asm読めば全て分かるだろうけど
203: ◆0uxK91AxII
09/11/05 23:23:50
TryEnterCriticalSection ~ Sleepだとどうなるの、っと。
threadをCPUと1:1にbindしたらどうなるの、っと。
timesliceを変えたらどうなるの、っと。
結果は書かない方が良い。
204:193
09/11/06 07:01:38
>TryEnterCriticalSection ~ Sleepだとどうなるの、っと。
これだけやってみた。
上記のテストだとインターロックとの差は0.5秒内、
つまりほとんど差がなくなった
205:デフォルトの名無しさん
09/11/06 13:00:12
プロセッサ数が2以上ならSpinWaitにしたらどうなる?
あとインターロックのIncrementでダイレクトアップデートにしたらどうなる?
206: ◆0uxK91AxII
09/11/06 20:26:47
違うネタだけど。
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#define THREADS 64
#define LOOPS 123456789
struct SData { LARGE_INTEGER m_cntBegin; LARGE_INTEGER m_cntEnd;};
DWORD WINAPI thread(LPVOID pArg);
int __cdecl cmpForSort(const void *pArg0, const void *pArg1);
int _tmain()
{
int i; HANDLE ahThread[THREADS]; SData aData[THREADS];
LARGE_INTEGER diff;
for (i=0; i<THREADS; i++)
ahThread[i] = CreateThread(NULL, 0, thread, &aData[i], 0, NULL);
WaitForMultipleObjects(THREADS, ahThread, TRUE, INFINITE);
qsort(aData, THREADS, sizeof SData, cmpForSort);
for (i=0; i<THREADS; i++)
{
CloseHandle(ahThread[i]);
diff.QuadPart = 0<i? aData[i].m_cntBegin.QuadPart - aData[i-1].m_cntBegin.QuadPart: 0;
_tprintf(_T("thread: %d, diffBegin: %I64d, clock: %I64d\n"), i, diff.QuadPart, aData[i].m_cntEnd.QuadPart-aData[i].m_cntBegin.QuadPart);
}
return 0;
}
207: ◆0uxK91AxII
09/11/06 20:28:49
DWORD WINAPI thread(LPVOID pArg)
{
SData *pData; DWORD value; float sum;
pData = (SData *)pArg;
QueryPerformanceCounter(&pData->m_cntBegin);
__asm
{
mov ecx, LOOPS
fldz
LOOP_:
fadd QWORD PTR value
dec ecx
jnz LOOP_
fstp DWORD PTR sum
}
QueryPerformanceCounter(&pData->m_cntEnd);
return 0;
}
int __cdecl cmpForSort(const void *pArg0, const void *pArg1)
{
LARGE_INTEGER diff;
diff.QuadPart = ((SData *)pArg0)->m_cntBegin.QuadPart - ((SData *)pArg1)->m_cntBegin.QuadPart;
if (0 > diff.QuadPart) return -1;
if (0 < diff.QuadPart) return 1;
return 0;
}
208: ◆0uxK91AxII
09/11/06 20:37:44
同じ処理なのに所要時間がブレるとか、
先に開始したthreadよりも、後から開始した方が早く処理を終えるとか。
そういうのが起こりうる。
computer gameでmulti threadの利用に消極的な理由の一つだと思う。
209:193
09/11/06 23:12:33
>>205
>インターロックのIncrementでダイレクトアップデートにしたらどうなる?
1.3秒だった
>SpinWait
これC#じゃん
210:デフォルトの名無しさん
09/11/07 01:40:37
スピン待機はC#限定じゃなく一般的な概念だ
211:デフォルトの名無しさん
09/11/07 09:40:03
スピンすると余計遅くなりそうだな。
一般的な使用状況に比べて処理と競合がタイトすぎるせいかな多分。
212:デフォルトの名無しさん
09/11/07 09:45:49
ああつまり3スレッド同時じゃなくて1スレッドで3回繰り返した方が速いとかっていう状態ね。
213:デフォルトの名無しさん
09/11/07 17:33:40
あーいやいや、これだとちょっと書き方がおかしいな…まあいいや
214:193
09/11/07 19:49:07
スピンロックは信頼性がないという話を聞いたような。
さて上記のベンチですが、1スレッドで3回繰り返したほうがずっと早いです。
衝突したときに別の処理をせずに待つ場合はシングルスレッドにした方がいいかも。
215:デフォルトの名無しさん
09/11/07 20:02:47
スピンロックに信頼性が無かったらどうすんだよw
全然仕組みとか分かってなくて使ってる匂いがぷんぷんするな
216:デフォルトの名無しさん
09/11/07 20:03:53
スピンロックとスピンウェイトは基本的に別物です。
217:デフォルトの名無しさん
09/11/08 00:12:02
それと信頼性に何の関係が?
218:デフォルトの名無しさん
09/11/08 02:55:49
スピン待ちの話をされてスピンロックどうこうと返すのがおかしい
219:デフォルトの名無しさん
09/11/08 10:06:21
上の人じゃないけど、スピンロックはスピンウエイトを使ってやってるかとおもてたよ(´・ω・`)
220: ◆0uxK91AxII
09/11/08 12:45:22
spinlockでlockできる保証は無いね。
偶然上手く動いているだけ。
221:デフォルトの名無しさん
09/11/09 01:48:53
◆0uxK91AxIIで検索したら、NGしてもいいくらいトンチンカンな奴だな
222:デフォルトの名無しさん
09/11/10 14:27:27
トリップ付けるような奴だもの。
223:デフォルトの名無しさん
09/11/10 20:06:21
トンチンカンなんて久々に見た
おやつあげないわよ
224:デフォルトの名無しさん
09/11/11 09:14:41
抜作先生の方がまだ新しいな。
225:デフォルトの名無しさん
09/12/15 00:01:41
マルチスレッド対応の基数木のアルゴリズムって
どうやって記述すればいいのでしょうか?
CかC++で探しています。
226:デフォルトの名無しさん
09/12/22 22:31:16
読み込みと書き込みが1スレッドずつの場合でもメモリ破壊って起きるのでしょうか?
たとえば、ある変数をメインスレッドで読み込み続け、
複数のサブスレッドで、クリティカルセクションを用い、書き込むといった場合です
227:デフォルトの名無しさん
09/12/22 22:39:31
>>226
とりあえず破壊読み出しメモリだと死ぬよね。
228:デフォルトの名無しさん
09/12/22 23:29:29
>>226
まずメモリ破壊を定義してもらおうか
229:デフォルトの名無しさん
09/12/23 01:41:11
パソコンのネジ外して開けると見えてくるメモリの部分をハンマーで叩く
230:デフォルトの名無しさん
09/12/23 01:42:27
ハードウェア的な話題もするんか
231:デフォルトの名無しさん
09/12/23 02:21:03
宇宙線による確率的なビット反転は防ぎようがない
232:226
09/12/23 10:10:00
データが飛ぶという意味でのメモリ破壊です
ハード的にどのように動作しているのか分からないのですが
同アドレスに同時にアクセスされることによってメモリ破壊が起きるのでしょうか?
233:デフォルトの名無しさん
09/12/23 10:20:05
書き込みをクリティカルセクションで同期して、クリティカルセクションを抜けたところで可視性が保証されたとしても、
読む方が書き込み中にその変数を見る可能性があるなら、少なくとも意図しない値を読む可能性はあるんじゃない?
(+不変な変数見てると思われるかもね)
要求次第だけど、
この手のポーリングするやつは、次に読めればいいからその瞬間のスナップショットで十分だと思うので、
Atomicな操作用のAPI使うとか、書き込みがAtomicであることが保証されるならvolatileだけでもいいかも。
その変数の読み書きだけ同期とっても、読んでる間の書き込みは防げても、
読み込みが終わってクリティカルセクション抜けたあと、それで処理しようと思ったら
もう書き換わってることもあるし。
読んだ値の処理が終わるまで書き込ませないなら、話は別だけど。
234:デフォルトの名無しさん
09/12/23 11:15:37
昔使ったタイマ LSI でラッチ→lo-read→hi-readって
いう約束ごとのあるやつがあったな。hi-readでラッチ
が外れる奴。word-read 命令が使えるかどうかは CPU
次第。
235:デフォルトの名無しさん
09/12/23 12:47:17
>>226
ハードや操作による。
つーか、まずは「アトミックな操作」という概念をどっかで調べとけ。
例えば、x86のCPUなんかだと、どういう操作がアトミックかはIntelが規定している。
アトミックな書き込みなら、別のコアからの読み込みが割り込む可能性は無い。逆に
アトミックでない書き込みなら、例えば半分くらい書き込んだところで別のコアが
読み込む可能性があるということ。
x86なら、厳密な規定はIntelの英語版サイトに落ちてる。32bitアラインドなreadや
writeは確実にアトミックだ。相当古いx86以外はキャッシュアラインドなら大丈夫。
read-modify-writeはLOCKプリフィクスが無い限りアトミックではないが、xchg
命令はLOCK#が自動的にアサートされるのでアトミックだ。
まぁ、アセンブラを直接叩くんじゃなければ、イントリンシック命令を調べておけば
十分だが、その裏でどういうCPUの動きをしているかは理解しといた方がいい。
つーか、低水準の話と高水準の話で全然違いすぎるんだよな。俺はどっちの話でも
構わんけど、分けた方がいいのか?
236:226
09/12/23 12:53:08
ありがとうございます
もっと勉強します
237:デフォルトの名無しさん
09/12/23 13:31:19
>>232
そんな事は起きないようにハードウェアが作られてる
物理的なメモリへのアクセス経路は1個しかないから、同じアドレスに同時にアクセス
なんて事は出来ない
命令が書いた順に実行されるかとか、他のコアやスレッド云々は >>235 の通り
238:デフォルトの名無しさん
09/12/23 13:31:47
クリティカルセクションを用いって書いてあるから、なんとなくWindowsかと思ってた。
239:デフォルトの名無しさん
09/12/23 13:32:15
>>235
ここはム板だから低水準の話はついていけないと思う
240:デフォルトの名無しさん
09/12/23 13:49:38
>>237
> 物理的なメモリへのアクセス経路は1個しかないから、同じアドレスに同時にアクセス
> なんて事は出来ない
いつの時代の人?
241:デフォルトの名無しさん
09/12/23 14:00:02
>>239
いやそれは無い
242:デフォルトの名無しさん
09/12/23 14:00:28
ん?今はどこが違うの?
243:デフォルトの名無しさん
09/12/23 14:04:04
>>235
x86は巨視的には古典的設計だからまだ理解しやすいけど、PPCなんかだとリオーダー
とかが剥き出しになってくるからさらにごちゃごちゃするんだよな
244:デフォルトの名無しさん
09/12/23 14:06:45
そこでeioioですよ!
245:デフォルトの名無しさん
09/12/23 14:07:20
間違えた、eieioだった
イーアイイーアイオー!
246:デフォルトの名無しさん
09/12/23 14:28:55
エイッエイッオッー
247:デフォルトの名無しさん
09/12/26 12:32:01
この辺の話題が体系的に書かれてる教科書が欲しい
248:デフォルトの名無しさん
09/12/26 14:41:39
開拓が進行中のジャンルだから、書いたそばから陳腐化しそうでなかなか難しいかも
しれないな
249:デフォルトの名無しさん
09/12/31 15:09:39
何をもって高性能とするかをはっきりさせたいな
シングルコア100%アイドル3コアでできることを4コア25%ずつで処理することに意味はあるの?
250:デフォルトの名無しさん
09/12/31 15:12:36
>>249
に追記
並列処理の有利はわかるけど、これからは直列処理も並列化しようとしてるんでしょ
そんなの意味ないよねという話
251:デフォルトの名無しさん
09/12/31 15:50:00
1コア100%3コア0%ってCPUがボトルネックになってんじゃねーの
252:デフォルトの名無しさん
09/12/31 15:50:26
何を言ってるの?
253:デフォルトの名無しさん
09/12/31 21:19:08
>>249は軽くエスパーが日本語に翻訳しないと分かりづらい
4スレッドにしたら全部25%になっちゃうような処理までマルチスレッドにする
意味あんの、って言いたいんだろうし、だからCPU屋は2コアや4コアで現状維持
しながら別の進化の方向性を探ってるのも事実
だがそもそも、そういう微妙なケースにまで頑張って適用しようぜMTマンセー、
というようなスレではないので、そんな的外れなこと言われても一瞬何の話だか
分からんし、今更何をとしか言いようがない
254:デフォルトの名無しさん
09/12/31 21:28:43
>>253
日本語でおk
255:デフォルトの名無しさん
09/12/31 21:35:30
>>253
余ってるCPUに仕事振る余地のない処理なら
それでいいんじゃね?
256:デフォルトの名無しさん
09/12/31 21:39:14
>>249の問題提起自体が微妙
アムダールの法則くらいで十分じゃねーの?
257:デフォルトの名無しさん
10/01/03 18:49:32
そもそも並列化できない処理まで並列化しようとしてるなんて話は聞いたこともない。
誰が言ったんだそんなこと。
258:デフォルトの名無しさん
10/01/03 21:49:55
>>249が言ってるな
259:デフォルトの名無しさん
10/01/16 03:00:47
質問させてください。
【OS】 UNIX/LINUX
【言語】 C言語
【実行環境】 gcc
【その他特記する事項】
メインスレッドからn個のスレッドを作成->全ての終了を待つという場合、
int i;
pthread_t id[n];
void* res[n];
for (i=0; i<n; i++) pthread_create(&id[i], NULL, funcptr, arg);
for (i=0; i<n; i++) pthread_join(id[i], &res[i]);
こんな感じで大丈夫でしょうか?
それとWindowsにあるWaitFor~みたいに複数待つというのは無いのでしょうか?
260:デフォルトの名無しさん
10/01/16 03:18:30
>>259
>WindowsにあるWaitFor~みたいに複数待つ
つ URLリンク(developers.sun.com)
261:デフォルトの名無しさん
10/01/26 00:12:16
スレッドを終了させないままアプリを閉じた場合
やっぱメモリリークとか起きるの?
262:デフォルトの名無しさん
10/01/26 00:20:29
環境を想定しないとなんともいえない。
263:デフォルトの名無しさん
10/01/26 00:33:22
>>261
OS破壊されるぞ?いいのかそんなことしても
264:デフォルトの名無しさん
10/01/26 00:49:27
>>261
ja.wikipedia.org/wiki/メモリリーク
265:デフォルトの名無しさん
10/01/26 10:22:10
破壊されるようなOSなんか使うなw
266:デフォルトの名無しさん
10/01/26 16:03:33
MTでそんな脆いOSはちょっと想像付かないなw
携帯の奴とかはどうなんだろう
267:デフォルトの名無しさん
10/01/26 16:15:09
問題(1) 名前を入れる入力ダイアログ1つとボタンを1つ表示し,ボタンを押したときは時間に応じて,
05時~11時 「おはようございます,○○さん」
11時~17時 「こんにちは,○○さん」
17時~05時 「こんばんは,○○さん」
と表示するJavaScriptプログラムを作成しなさい。
268:デフォルトの名無しさん
10/01/26 16:20:40
断る。
269:デフォルトの名無しさん
10/01/26 16:24:21
キミの実力を見せてみろ
270:デフォルトの名無しさん
10/01/26 16:28:23
マルチスレッドと何の関係が
271:デフォルトの名無しさん
10/01/26 16:32:31
スレ違いでした。
すいません・・
272:デフォルトの名無しさん
10/01/26 17:10:35
VCでマルチスレッドアプリをトレース実行してるとかなりの頻度でOSごと固まるんですが、
マルチスレッドの場合のデバッグはデバッガ使わないのが普通なんですか?
273:デフォルトの名無しさん
10/01/26 17:48:30
PCが貧弱
274:デフォルトの名無しさん
10/01/26 18:05:06
嫁が貧乳
275:デフォルトの名無しさん
10/01/26 18:13:39
ユーザが頻尿
276:デフォルトの名無しさん
10/01/26 18:19:25
>>272
詳細なテキストサービスをオフにすると少し幸せになれるかも。
ATOK使いの俺には無縁な話。
277:デフォルトの名無しさん
10/02/02 23:21:31
最近スレッド使い始めました。
クリティカルセクションとかインターロックで変数を共有するのは
なんとなく分かりました。
例えばCRITICAL_SECTIONを使う場合、アプリケーションで一つ用意すれば
よいのでしょうか?
極端に言えばCRITICAL_SECTIONをグローバル変数として定義して、
EnterCriticalSection等を使えばよろしいのでしょうか?
278:デフォルトの名無しさん
10/02/02 23:33:23
トイレに例えるなら何個個室があっても鍵がすべて連動してトイレにはひとりしか入れないってことだぞ
それでいいのか?
279:デフォルトの名無しさん
10/02/02 23:44:28
それでも良いが性能は良くない
性能向上のためにスレッドを使っているわけではないのなら、別に構わない
無理にシングルスレッドで処理するよりマルチスレッドの方が可読性が高くなることもあるからな
性能を上げたいのなら一人がどこかでロックを握ってる間全員が待たされるような構造は良くない
280:277
10/02/03 00:18:41
なるほど。問題点の指摘ありがとうございます。
では、3つスレッドがあるとして、1つは無関係で2つのスレッドで
変数を共有する場合は、クリティカルセクションをどう使えば
よろしいのでしょうか?
各スレッドループ中にCRITICAL_SECTIONを定義してりようすればよろしいのでしょうか?
何か根本的に勘違いしている気がしている気がします。
281:デフォルトの名無しさん
10/02/03 00:32:42
共有する変数がグローバルで1個しかないのならクリティカルセクションもグローバルで1個でいいよ
282:277
10/02/03 00:50:34
現在は全体からアクセスできる変数が一つです。
一気にやろうとはしないで少しずつ複雑なパターンを試してみます。
あと環境はWindowsです。失礼しました。
283:デフォルトの名無しさん
10/02/03 01:35:14
まあロックが1つで済むならデッドロックとか考えなくて済むし
可能ならその方が悩まない。
パフォーマンスの問題は、占有期間次第とも言えるから。
284:デフォルトの名無しさん
10/02/03 02:19:04
クリティカルな部分一個をトイレの個室一つと考える
285:デフォルトの名無しさん
10/02/03 04:12:03
たまに鍵かけないやつがいてトラブるんだ
286:デフォルトの名無しさん
10/02/03 07:23:37
そうするとトイレの中に
トイレがあって、その中にまたトイレがないと
説明不可能だろ。
トイレはネストできねーだろ
287:デフォルトの名無しさん
10/02/03 09:11:21
そうかクリティカルセクションはネスト出来たか
288:デフォルトの名無しさん
10/02/03 11:33:20
じゃあトイレがバスルームにあるということで
289:デフォルトの名無しさん
10/02/03 11:42:57
階層数に制限があるからダメ。
290:デフォルトの名無しさん
10/02/03 11:52:56
トイレ中に地震がくるのと
小便中に大便を催すのと
どっちが我慢できる?
291:デフォルトの名無しさん
10/02/03 13:45:14
メモリバリアとmutexの関係が解りません。
メモリバリアとmutexがどういうものか。とかじゃなくて、
関係性とか、必要とされる場面について解説してあるサイトないですか?
292:デフォルトの名無しさん
10/02/03 13:59:08
メモリバリア
URLリンク(ja.wikipedia.org)
メモリバリアは単に自CPUのメモリアクセスの順序を制御するだけのもので、
mutexのようなスレッド間の排他制御 (後続のスレッドを進入させずに待たせるような) 機能は無い
メモリバリアはCPUの1命令に過ぎず、mutexはOSのスレッド管理と絡むもっと複雑なものだ
mutexを実装するOSの中の人は、複数のCPU間の連携のためにメモリバリアを使うかもしれない
293:デフォルトの名無しさん
10/02/03 16:33:38
メモリバリアかアトミック命令が無いとMutexは実装出来ない
294:デフォルトの名無しさん
10/02/03 20:55:32
>>291 は同期処理のバリアのことじゃないの?
URLリンク(ja.wikipedia.org)
ロードストアのオーダリングの話と mutex はちょっと離れてる気がする
295:デフォルトの名無しさん
10/02/04 17:45:59
>>286
クリティカルセクションのネストって必要かな?
296:デフォルトの名無しさん
10/02/04 17:49:29
クラスのスレッドセーフなメソッドから同クラスのスレッドセーフなメソッドを呼び出す場合とかにあると便利かも
そういう動作を意図しなかった場合にバグらないっていう利点もあるね
297:デフォルトの名無しさん
10/02/04 17:55:39
同クラスなら同期処理しないプライベートメソッドを呼び出すのではないか
298:デフォルトの名無しさん
10/02/04 19:04:48
たとえば口座aから口座bに振替をおこなうには、
口座aと口座b両方のロックを取る必要がある、
という典型的な例は?
299:デフォルトの名無しさん
10/02/05 08:24:35
それは二つのCSをロックするだけでネストじゃないんでね?
300:デフォルトの名無しさん
10/02/05 09:08:04
こんな話題とメモリバリアの話題が同時進行するってかなりカオスな気がする
301:デフォルトの名無しさん
10/02/05 13:10:17
>>298
同時に入ってる必要は無くね?
302:デフォルトの名無しさん
10/02/05 21:40:05
両方とも、a→bの流れならトランザクションだけでよくないか?
303:デフォルトの名無しさん
10/02/06 00:40:47
スレッドがA、B、C、Dの4つあって
かならずA、B、C、Dの順番で仕事が
終わるようにするには
どんなアルゴリズム使えばいいのですか?
304:デフォルトの名無しさん
10/02/06 00:46:46
スレッド化する意味あるのか?
B,C,Dは寝かせておいて、Aが自分の仕事を終えたときにBを起こせばいいんじゃないか
305:デフォルトの名無しさん
10/02/06 13:44:25
スレッドの終了処理を順番にやる必要があるってことかな。
終わるタイミングを調整したいだけなら、
BがAの終了を待つ
CがBの終了を待つ
DがCの終了を待つ
って感じにやれば順番に終われるんじゃね?
306:デフォルトの名無しさん
10/02/06 18:28:33
そしてAがDの終了を待てば完璧
307:デフォルトの名無しさん
10/02/06 19:34:45
>>306
どうやって全部待てばいいの?
308:デフォルトの名無しさん
10/02/06 20:36:58
Eに管理してもらう
309:デフォルトの名無しさん
10/02/06 20:51:33
どうやるのか全然わからない
たすけて
310:デフォルトの名無しさん
10/02/06 22:14:37
Aの処理終了の際に2個のスレッドで破れるBarrier1を待つ
Bの処理開始の際に2個のスレッドに破れるBarrier1を待つ
Bの処理終了の際に2個のスレッドに破れるBarrier2を待つ
Cの処理開始の際に2個のスレッドに破れるBarrier2を待つ
Cの処理終了の際に2個のスレッドに破れるBarrier3を待つ
Dの処理開始の際に2個のスレッドに破れるBarrier3を待つ
311:デフォルトの名無しさん
10/02/06 22:16:11
>>310
>スレッドで破れるBarrier
こんなことすると破綻すると思うのですが
それは何か新しい概念なのでしょうか?
312:デフォルトの名無しさん
10/02/06 22:46:53
>>311
>>294のバリアのことだよ。
2個のスレッドがバリアに到達した瞬間にバリアが破れて同時に進行を再開する。
Wikipediaより…
並列コンピューティングにおけるバリア(英: Barrier)とは、同期方法の一つであり、
ソースコード中でスレッドやプロセスがある箇所で停止し、
他の全てのスレッドプロセスがバリアに到達するまで進行しないようなものを示す。
313:デフォルトの名無しさん
10/02/07 00:29:35
>>310
わかりにくい表現だな。
314:デフォルトの名無しさん
10/02/07 21:28:39
同期なり待機って言った方がわかりやすいな
315:デフォルトの名無しさん
10/02/11 00:13:07
追加削除順序を保持しつつ
効率的にアクセス可能なデータ構造って何があるの?
316:デフォルトの名無しさん
10/02/11 00:25:04
二分木
317:デフォルトの名無しさん
10/02/11 00:32:33
>>316
マルチスレッドの2分木のサンプル
教えて
318:デフォルトの名無しさん
10/02/11 00:50:06
>>315
Skip list.
実装例は java.util.concurrent.ConcurrentSkipListSet とかかな。
319:デフォルトの名無しさん
10/02/20 11:14:34
C++のマルチスレッドの本って
どんなのがありますか?
Intelの本は使い方しか書いてないで
困ってる
320:デフォルトの名無しさん
10/02/20 12:39:32
正直、使い方だけしか提示しようがない気がする
どこもかしこも開拓中で、定番というものが無い
321:デフォルトの名無しさん
10/02/21 18:06:11
>>319
Java並行処理プログラミングマジオススメ。
直接同じことは出来なくても、考え方は大いに参考になる。
volatileだけはC++と全くの別物なので注意だけど。
boost.threadのfutureでJavaのExecutorフレームワークに近いことが出来そうだなぁ。
322:デフォルトの名無しさん
10/02/21 18:16:04
>>321
その程度の書籍薦められても困るんだよ
もっとまともな本持って来い
323:デフォルトの名無しさん
10/02/21 18:29:39
>>322
Java並行処理プログラミングでも満足できない貴方には
↓がお勧め。
URLリンク(scholar.google.com)
最先端の研究成果が大量に手に入るぞ。
324:デフォルトの名無しさん
10/02/21 19:01:28
>>322
もっとまともな本があるなら俺も知りたいけどね。
325:デフォルトの名無しさん
10/02/21 23:35:25
並行コンピューティング技法―実践マルチコア/マルチスレッドプログラミング
URLリンク(www.oreilly.co.jp)
326:デフォルトの名無しさん
10/02/22 16:37:56
begintreadexを使ったときはclosehandleを使わないといけないらしいけど
CloseHandle((HANDLE)_beginthreadex());
こんな感じでいいの?
327:デフォルトの名無しさん
10/02/22 16:42:48
beginthreadexが返したハンドルを渡すのかと聞いているのならYES
328:デフォルトの名無しさん
10/02/22 17:44:29
_beginthreadexはなんで整数型で返すんだろう
329:デフォルトの名無しさん
10/02/22 22:11:07
Win32の型を持ち込みたくなかったからじゃないの。
330:デフォルトの名無しさん
10/02/23 00:27:00
意味も無く汚くはしないしな、いくらMSでも
331:デフォルトの名無しさん
10/02/23 00:29:08
void *じゃだめなのか
332:デフォルトの名無しさん
10/02/23 08:52:12
それだと32bitであることを強調できないからやめたんじゃないかな
333:デフォルトの名無しさん
10/02/23 14:32:40
一応今はuintptr_tだしな
まぁ毎度のレガシーの枷なんだろうし、仕方ないっつーか正直どうでもいい
334:デフォルトの名無しさん
10/03/07 15:36:02
どちらかというとマルチコア絡みの質問ですが
テンプレにある該当スレは過疎ってるぽいのでこちらで質問させていただきます
Q1. Windowsはスレッドコンテキスト切替時、汎用レジスタ同様にxmmレジスタを待避/復帰しますか?
主にWindows 7 (32 bit)とWindows 7(64 bit)について知りたいですが、他のも回答いただけると有難いです
Q2. そもそもCore i7のSIMDモジュールってコア毎に独立してますか?
独立してるっぽいけど、確証となるブロックダイアグラムみたいなのがIntelのドキュメントを漁っても見つからないorz
Q3. Core i7の分岐予測メモリって、コードが共通なら全スレッドで共通?それともスレッドコンテキスト毎にきちんと別統計になるんでしょうか?
Q4. VC(2008)付属ライブラリの数学関数(おそらくコプロセッサを使うはず)はスレッドセーフですか?またそれは/fp:オプションによらず不変?
よろすくおながいしますorz
335:デフォルトの名無しさん
10/03/07 16:24:51
A1: Windows 98, 2000以降はyes
A4: yes
336:デフォルトの名無しさん
10/03/07 16:51:28
A2 コア別でしょう。たぶん。コア間共有なんて設計のほうが難しいと思うよ。
A3 コア別でしょう。たぶん。コア間共有なんて設計のほうが難しいと思うよ。
337:デフォルトの名無しさん
10/03/07 17:32:40
>>326
>CloseHandle((HANDLE)_beginthreadex());
その組み合わせはちょっちまずくね?
URLリンク(msdn.microsoft.com)
にメモリリークが起きると書いてある(ちなみにやねうら本(1)にもそう書いてある)
ExitThread()を明示的に呼ばなくても、スレッド関数を抜けたら同じことのはず
なお、>326の反対(CreateThread()が返したハンドルを _endthread()で開放する)は明白に危険であろうことが上のリンク先から推測できる
(確保されていないメモリを_endthread()が解放しようとするハズ)
338:デフォルトの名無しさん
10/03/07 18:07:36
何のために_beginthread()~_endthread()や_beginthreadex()~_endthreadex()があるかというと
strtol()みたいに、機能的にはマルチスレッド環境下でも動いて欲しいのだが関数仕様的にマルチスレッドと相容れないような
標準関数をマルチスレッド環境でもきちんと動くようにする目的なので(おそらくそのために内部的にスレッド局所記憶を確保している)
そういう類の関数を明示的にも暗黙的にも呼び出さないと誓うならCreateThread()~CloseHandle()で無問題
339:308
10/03/07 18:19:56
スマソstortol()じゃなくて問題なのはstrtok()とかlocaltime()とかだった、
340:デフォルトの名無しさん
10/03/07 18:53:55
>>337
_beginthread は起動されたスレッドが終了時にハンドルのクローズを行う。
_beginthreadex は別途CloseHandleする必要がある。その代わり、
スレッドが終了していてもハンドルは有効であり、スレッドの状態を調べることができる。
ここでのリークというのはCRTの作業域のことではなくて
あくまでもスレッドを追跡するためのハンドルのこと。
341:デフォルトの名無しさん
10/03/07 22:27:39
>335, >336
レス㌧クス
A1は実験的にも確認できた(イントリンシック関数が排他を含まないこと、およびxmm0とxmm1を使う関数を64スレッドで呼び出して無問題)
A2はまあそう思う(ダイ写真でSIMDとコアの区別を確認できない&SIMDの数<コアの数ではマルチメディア目的に合致しない)
A4についても使用予定関数について実験的に確認できた
A3はちょっち謎
同一コードで記述され、同一コアで走る別スレッド(含HT)の場合どうなるのか?
同一コード条件とそうでない条件(コードをスレッド別コピーとする)とで速度比較すればいいんだろうけども
コードをコピーすると分岐予測以前にトレースキャッシュ容量他の要因で速度低下するかもしれないから実験では精度良くは判断できない鴨
342:デフォルトの名無しさん
10/03/08 00:36:48
pthread_cond_wait状態になるまでに
結構時間かかるのですかね?
以下のようなコードを実効すると
結構頻繁に、別のスレッドがwait状態になる前に
pthread_cond_signalを実効してしまうのですが
必ず、同期取るようにどうしたらいいのでしょうか
thread1
{
while(1){
pthread_mutex_lock(&m);
pthread_cond_wait(&c, &m);
pthread_mutex_unlock(&m);
}
}
main
{
while(1) {
pthread_mutex_lock(&m);
pthread_cond_signal(&c, &m);
pthread_mutex_unlock(&m);
}
}
343:デフォルトの名無しさん
10/03/08 00:39:08
どうやって確認したの?
344:デフォルトの名無しさん
10/03/08 00:45:01
何がしたいのかよくわからんが、
とりあえずmutex取得する前にシグナル発行してたらいかんだろう。
345:デフォルトの名無しさん
10/03/08 00:54:13
thread1がlockするまえにmainがlock->signalしちゃってるとかありそう
346:デフォルトの名無しさん
10/03/09 07:06:51
>>337-338
つーか比較するものが間違ってる
_endthread()/_endthreadex()は作られた側が(必要なら)呼び出すもので
CloseHandleは_beginthread()/_beginthreadex()呼んだ側が呼び出すもの
347:341
10/03/13 23:42:54
自己解決しますた!(いや、多分、だけど
Windowsのスレッドコンテキスト切替は、スレッドが走り続けている場合、どうがんばっても
msオーダー周期(おそらく10 msとか20 msに1回)なので、分岐予測統計の結果がその間に十分安定する(と思われ
だから分岐予測精度を上げるためにコードのコピーをスレッド別に用意しておく、みたいな神経質なことはしなくて宜しい
かと、
348:342
10/03/14 01:04:34
訂正
誤:分岐予測統計の結果がその間に十分安定する(と思われ
正:分岐予測統計の結果が現実的に安定している期間よりも桁違いに長い(と思われ
ニホンゴ、ムズカシイデス、、
349:デフォルトの名無しさん
10/03/14 02:03:43
いやいやいやいや
いまはコア間での話ではなかったのか?
350:デフォルトの名無しさん
10/03/14 08:00:00
またえらい細かいオーダーで削ってるんだなぁ。
PCのWindowsでそこまでカツカツ削っても、すぐに時代変わっちゃうと思うけどなぁ。
他のとこに力入れた方が良くね?
まぁ、トレースキャッシュとか気にしてるから、何か特殊な固定環境向けのガリガリな
チューニングなのかもしれないけど。
俺も低レベルは好きだから、とりあえず触ることで知識と感覚を深めたい、ってんなら
止めないけど。単にバランス感覚の欠けてるケースに見えてしまうが。違ったらすまん。
351:デフォルトの名無しさん
10/03/14 08:19:21
>>349
分岐予測メモリはCore i7の場合物理コアごとに持ってるからスレッドごとに物理コアを違える場合は何も悩む必要はない
問題なのはスレッドの数が物理コア数より多いとか、同一物理コア内でのHTの場合(→341の下から3行目参照)
352:デフォルトの名無しさん
10/03/14 08:30:59
ハッよく考えたら>348-349のロジックじゃあHTの場合が解決してねーじゃんorz
同一コア内で走るHT0とHT1は、ハードウェアレベルで演算ユニット、L1, L2キャッシュ、トレースメモリを奪い合うので
もし仮に分岐予測メモリのタグがアドレスのみから生成され、HT番号では区別されない作の場合問題になりえる
ただしまあ現実的には同じアドレスに配置された同じ条件分岐命令が
1. HT0とHT1でほぼ同時に(=分岐予測結果の平均寿命(おそらく数μsec)オーダーの時間差内に)実行されるという状況が
2. 片方は分岐、片方は非分岐で
3. 無視し得ない頻度で反復される
というケースでのみ問題だが
>>350
というわけでWindows非依存な話
353:デフォルトの名無しさん
10/03/14 08:32:37
>>352
いや本人がWindows7を対象にしてるって最初に言ってるから
354:デフォルトの名無しさん
10/03/22 00:57:55
>>342
亀だが、それは条件変数の使い方を間違えとる
いきなり無条件でcond_waitで待ってはいかん
cond_waitは、あくまで「共有条件が望む状態になっていない時」に使うものだ
cond_wait時に指定するmutexは、その「共有条件」をテストするためのものだ
でもってcond_signalやcond_broadcastは、共有条件の変更があったことを通知して、共有条件の再テストの機会を与えるものだ
なお、cond_signal, cond_broadcastの実行そのものには、mutexの取得は必要ない
JMなんかのpthread_cond_initのmanページを見て、使用例を確認すると良い
355:デフォルトの名無しさん
10/03/27 11:48:41
pthreadの記事を見つけたので読んでたら、
なんかコメントで色々指摘が入ってるんだけど、どうなの?
URLリンク(codezine.jp)
356:デフォルトの名無しさん
10/03/27 15:08:07
ここのコメント欄みづらいんだよね
最初の「必要以上に複雑になってる」という指摘は同意。
この記事って、バグのあるコードをだんだん直していくっていう
流れだけど、そもそもタイトルの条件変数関係ないバグだし、
修正内容も、なんか泥沼に入っていくような感じ
その後のやりとは、この二人にしか分からないどうでもいいことについて、
どうでもいいやりとりしてるように見えた。
357:デフォルトの名無しさん
10/03/27 15:20:18
>>338
これはわかりやすい!
358:デフォルトの名無しさん
10/03/29 23:05:41
「Java並行処理プログラミング」が増刷してる
359:デフォルトの名無しさん
10/04/18 10:57:03
va_argsってスレッドセーフですか?
360:デフォルトの名無しさん
10/04/18 21:21:11
va_list を自動変数やTLBに置いていれば、va_listをスレッド間で共有しない限りは、スレッドセーフだと思うぞ。
361:デフォルトの名無しさん
10/04/18 22:11:15
>>360
嘘ついちゃだめ
va_listはプロセスで1つだけしか持てないから
スレッドセーフじゃないよ
362:デフォルトの名無しさん
10/04/19 00:34:37
ボナンザ8コア対応を16コア対応にする方法を教えて下さい。
363:デフォルトの名無しさん
10/04/19 06:51:44
スレッドセーフかどうかってのはcrtのソース見ないと判断付かないって認識でおkっすか?
364:デフォルトの名無しさん
10/04/19 07:04:05
>>361
適当ぶっこくなカス
365:デフォルトの名無しさん
10/04/19 07:18:38
>>364
じゃあ証明してくれよ
できないだろw?
366:デフォルトの名無しさん
10/04/19 07:28:20
>va_listはプロセスで1つだけしか持てない
367:デフォルトの名無しさん
10/04/19 07:59:36
それとスレッドセーフの話にどんな関係が?
368:デフォルトの名無しさん
10/04/19 08:31:37
>>365
簡単。
va_listはプロセスで複数もてるから
スレッドセーフ
369:デフォルトの名無しさん
10/04/21 11:18:50
すみません、spin-lockをしている間にCPUの使用率を下げる方法を知っている方はいますか?
調べてみると、rep;nop命令やSSEのpause命令をがそれに該当するように思えるのですが、
使ってみても何ら変わりませんでした。
自作のスレッドバリア関数(自作のspin_lock)を作って、
たとえば、
if(threadnum=5) sleep(10);
my_barirrer();
とするとスレッド5を待っている間は5以外のCPU使用率が100%近くなってしまいます。
それに対してOpenMP使った場合では、
if(threadnum=5) sleep(10);
#paragma omp barirrer
だと待っている間はCPU使用率は殆ど変わりません。
ちなみに自作のspinlockは下記のような感じです。
if(thread_num == 0)
{
asm volatile(
"Loop1:\n\t\t"
"movl (%0), %%eax\n\t\t"
"movl (%1), %%ebx\n\t\t"
"lfence\n\t\t"
"cmpl %%ebx, %%eax\n\t\t"
"rep;nop\n\t\t"
"jne Loop1\n\t\t"
:
:"r"(&lock->sync), "r"(&lock->maxthreads)
:"memory","%eax","%ebx"
);
370: ◆0uxK91AxII
10/04/21 15:37:33
>>369
方法はあるけど、物凄くマヌケで無意味だから誰もやらない。
371:デフォルトの名無しさん
10/04/21 19:01:35
スレッドとかの切り替えを自前で用意するとか
372:369
10/04/22 09:40:25
いろいろと試してみたのですが、マヌケな方法しか思いつきませんでした。
(スピンを何回かしたら、nanosleepを使うとか)
pthreadのライブラリのソースを見てみると、futexのシステムコールが呼ばれているようですね。
OpenMPで生成したスレッドの中で実行される関数間でスレッドの同期をとりたかったのと、
せっかくOpenMPを使っているから、
pthreadとか使いたくなかったので自前のspin_lockを作ってみました。
マヌケな質問をしてすみませんでした。
373:デフォルトの名無しさん
10/05/08 03:22:14
ヒント:スピンロックを使わない
374:デフォルトの名無しさん
10/05/09 22:01:03
Win32でスレッド間のイベント通知をやりたいんですが
2つのスレッドが同時にそれぞれSetEvent(), ResetEvent()を呼び出した場合の動作って定義されてるんでしょうか?
やっぱりクリティカルセクションで囲ってやらないとまずいですか?
375:デフォルトの名無しさん
10/05/09 22:39:08
>>374
囲む必要は無い。
376:デフォルトの名無しさん
10/05/10 08:17:54
>>375
ありがとうございます。
377:デフォルトの名無しさん
10/05/10 20:41:23
イベントオブジェクト自体の動作には問題ないけど、
使い方ミスりやすいから十分気を付けた方がいいよ。
378:デフォルトの名無しさん
10/05/10 23:08:00
プロのコードではイベントオブジェクトは使われない
379:デフォルトの名無しさん
10/05/10 23:37:24
配布したときに問題が出るからな
380:デフォルトの名無しさん
10/05/11 03:50:40
どんな?
381:デフォルトの名無しさん
10/05/12 22:45:33
無名にすれば他のプロセスと衝突することも無いし、kernel32.dllだから別にDLLも不要だし問題が思いつかないな
382:デフォルトの名無しさん
10/05/13 07:37:01
なんか勘違いしてんだろ
383:デフォルトの名無しさん
10/05/16 21:15:32
wait-freeなキューの実装を可能にするのに必要な不可分操作ってどんなんですか?
384:デフォルトの名無しさん
10/05/16 23:08:56
候補となる不可分操作には何があるの?
385:383
10/05/16 23:57:41
>384
JAVAのConcurrentLinkedQueueだとCASをつかってるってことしか知りませんが..
386:デフォルトの名無しさん
10/05/18 00:45:56
wikiによるとcasみたいだね
URLリンク(ja.wikipedia.org)
387:デフォルトの名無しさん
10/05/20 23:12:58
スレッド間のヘルスチェックに定番な方法ってあるのでしょうか?
・マスターなスレッドAが外部変数にスレッド数分bit1を立てる
・B以降のスレッドは、自分に対応するbitを落とす
・一定時間、0じゃなかったら誰かが止まってるのでNG
とかすると、sem_wait()で普段寝ている人(これはその時だけ起こせばいい?)や、
recvやselectで待ってる人の確認はできない。。
388:デフォルトの名無しさん
10/05/21 00:00:00
スレッドのヘルスチェックって要るのかな?プロセス間だったら必要かも知れなけど。
389:デフォルトの名無しさん
10/05/21 00:05:09
大事な役割を持ったスレッドが刺さってないか確認したいんじゃないの
390:デフォルトの名無しさん
10/05/21 01:47:25
タイムアウト指定して待ちっぱなしにならないようにするのが基本
391:デフォルトの名無しさん
10/05/21 18:56:29
ワーカースレッドとUIスレッド分けたとき、時間のかかる作業を
ワーカースレッドがしているとき、UIスレッドはどうしているべきでしょうか
今は終わるのを待たずに終わるまでデータ変更の起こる操作を禁止しています
でもそれだとウィンドウ動かせるくらいしかメリットがないので考え中です
392:デフォルトの名無しさん
10/05/21 19:03:15
>>391
俺は[中止]ボタンが押されるのを待つか、タイマーで定期的に終了したかどうか
チェックしてる。あとプログレスバー表示。
393:デフォルトの名無しさん
10/05/21 19:49:50
ボタンを禁止にしたりキャンセルを受け付けたり面倒だよな
それとプログレって、量的な変化ならいいが、
手続き的な進行表示には不向きだよな
394:デフォルトの名無しさん
10/05/21 20:05:26
全体量がわからないやつはつらいよね
\-/-\-...ってやつが好きw
395:デフォルトの名無しさん
10/05/21 21:03:40
経過表示なら1/n「(説明)」~n/n「完了」でいいと思うんだ
396:デフォルトの名無しさん
10/05/24 23:34:30
progress_display「呼んだ?」
397:デフォルトの名無しさん
10/05/25 09:11:50
いや、全然呼んでないよ
398:デフォルトの名無しさん
10/06/26 14:48:12
マルチスレッド・アプリケーション開発のためのインテル・ガイド
URLリンク(www.xlsoft.com)
399:デフォルトの名無しさん
10/06/27 14:54:02
>>391
おれはその処理に関連するメニューだけロック(選択不可とか無視とか)して他の操作は許可してる
処理が終わったら通知ポップアップ
処理状況なんかはモーダレスじゃないプログレスバーかステータスバー表示
400:デフォルトの名無しさん
10/06/27 15:01:41
>>393
でも長時間うんともすんとも言わないと不安になるからそういう場合は一秒に一ブロックぐらい進むプログレスバー繰り返してる
中止は処理スレッドに定期的に中断フラグチェックさせてプログレスバーダイアログのOnClose/OnCancelで終了フラグOn+WaitForSingleObjectさせればOK
401:デフォルトの名無しさん
10/07/02 23:09:47
URLリンク(blogs.wankuma.com)
なんかえらい絡まれてるくらい突っ込まれてるみたいなんだけど
やっぱりこの記事おかしいの?
それともコメントの方がおかしい?
402:デフォルトの名無しさん
10/07/02 23:28:25
>>401
バブルソートを題材にするとか並列化のサンプルとして適切じゃないというかフェアじゃないというか、あえてそれを選ぶのはなぜ?って話でしょう。
403:デフォルトの名無しさん
10/07/02 23:40:12
>何でもかんでも並列化すれば、等しく速くなるわけではない
記事の結論には同意だけど記事書いてるひとはアホ
404:デフォルトの名無しさん
10/07/03 02:56:46
>>403
同意だな。
並列化に向いたアルゴリズムをつかわにゃ早くならんしな。
ていうか変数shareしすぎ。
405:デフォルトの名無しさん
10/07/03 08:13:40
だらだらと下手糞なコードを書いて速くならねえよと喚かれてもな
そんな記事にはほとんど価値がない
406:デフォルトの名無しさん
10/07/03 09:47:23
結局バグってたっぽいw
コメントが間違ってなければだが。
407:デフォルトの名無しさん
10/07/03 10:07:39
記事自体は、アルゴリズムによって効率的に並列化できるとは限らないから云々んという内容なので、
記事自体が(素人にとっては)無意味だとまでは言わんが、
この人偉そうな言い方したり他人の記事に対しては重箱レベルで突っ込んだりもしてるくせに
自分の記事は内容が結構いい加減なんだよな。
408:デフォルトの名無しさん
10/07/03 11:48:12
そんな人は世間にはいっぱいいる
409:デフォルトの名無しさん
10/07/03 23:15:55
「並列処理は~」と一般化された題材に対して、帰納法で証明しようとしているのが問題かな
「マルチスレッドに向かないアルゴリズムがある」というテーマならこの方法で十分だけど
410:デフォルトの名無しさん
10/07/04 00:08:29
むしろ、そうじゃない人を見たら驚く。ライターなんてゲームの販売と同じ。
品物を売るまで、記事を読ませるまでが勝負。その後や内容なんて気にしなくてよい。
411:デフォルトの名無しさん
10/07/04 00:24:14
ライターじゃないだろ
412:デフォルトの名無しさん
10/07/04 00:39:12
金とってんのか
413:デフォルトの名無しさん
10/07/04 00:39:57
ひとをみたらライターと思え
414:デフォルトの名無しさん
10/07/04 17:20:36
ゲームの販売と同じなら、クソゲー売り続けるのと名作売り続けるのじゃ全く末路が
違うことくらい分かるだろうにアホか
415: ◆0uxK91AxII
10/07/04 20:15:36
>>401
記事を書いている本人が明らかに知識不足で、可笑しい。
テキトーに眺めただけで、コイツはダメだって分かるレベル。
416:デフォルトの名無しさん
10/07/04 20:54:04
並列化したプログラムの例として、アトミックな足し算使った合計計算のコードを出すような人だからな。
何がしたいのかさっぱりわからんレベル。
ほんとにまともなマルチスレッドのプログラム書いたことあるんかと。
417:デフォルトの名無しさん
10/07/04 21:44:51
>アトミックな足し算使った合計計算
とりあえずPageRankみたいな巨大行列計算だと使うんじゃないかな。
並列化というより分散化したいレベルだけど。
418:デフォルトの名無しさん
10/07/04 22:58:48
まともに組んだことがない人の記事だな
419:デフォルトの名無しさん
10/07/05 20:30:55
まあそこまで批判するべきことじゃない
わからないから試すのであって、わかるならする必要はない
まあ公開するならそれなりに検証して見栄を張るべきだとは思うけどねw素直すぎる
420:デフォルトの名無しさん
10/07/05 21:43:17
MTでパフォーマンス出すには、理屈を理解する頭が無いとどうしようもない気はする
421:デフォルトの名無しさん
10/07/05 22:06:11
分からないから試す、にも二通りある
「何が分からないかを分かった上で試す」のか
「何が分からないかも分からないまま試す」のか
まぁ>>401に関しては、ほんとにチラ見しただけでバカ記事っつーか、むしろ真面目に
叩いて貰えてるだけ幸せなんじゃね?
いやマジで、俺ならこんなのに関わる気にもならんわ。
どうせバカ記事書いた本人は「めんどくせぇのに絡まれたわ」程度にしか思わねーんだろ
と思うとなぁ。
422:デフォルトの名無しさん
10/07/05 22:20:05
>>419
この人の並列処理関連のいろいろなブログ記事とかCodeZineの記事ね、
元々ほかの人の並列処理関連の記事の批判から始まってるんだよね。
ばかなこと書いてるやつがいるので俺が訂正してやるって、
ほんとにこういう感じなのね。
で、あの記事なんだわ。
423:デフォルトの名無しさん
10/07/05 22:23:21
>>421
なぜ?氏の指摘はやっぱりおおよそ的を射てる内容なのかな?
424:デフォルトの名無しさん
10/07/05 22:27:57
つうか着々と増え続けとる…
425:デフォルトの名無しさん
10/07/06 19:33:04
へえ
426:デフォルトの名無しさん
10/07/06 20:01:42
ほぉ
427:デフォルトの名無しさん
10/07/07 22:49:02
>まともに組んだことがない人の記事だな
URLリンク(blogs.wankuma.com)
まともに組んだことはあまりないようだなw
428:デフォルトの名無しさん
10/07/07 23:20:11
なぜ?
Posted @ 2010/07/07 22:46
>スレッドの終了を、もうちょっとスマートに待てないのかなぁ?まぁ、動いてるからいいや。
全然よくありません。
Sleep(0)を入れているとはいえ、無駄なループでCPUを使用していては、まともな計測はできません。
コア数以上にスレッド数を増やしても改善していってしまうのは、これも原因なのではないですか?
>おかしいと思ったらできるところまで追求する。それが職人ってもんじゃないですかねー。似非職人はヤーネー。
いくらなんでもこんなこと言いながらこれではダメでしょう。
429:デフォルトの名無しさん
10/07/07 23:44:31
本人に言えよ
430:デフォルトの名無しさん
10/07/07 23:57:00
おまえならできる
431:デフォルトの名無しさん
10/07/08 00:19:44
?
432:デフォルトの名無しさん
10/07/08 00:24:16
本人?
433:デフォルトの名無しさん
10/07/08 01:19:38
馬鹿が呟いているだけだから無視でいいだろ。話題にすらならん。
434:デフォルトの名無しさん
10/07/08 01:42:21
ヲチスレじゃないしな
もう少しマシな話題ならともかく、内容がどうでもよさすぎる
435:デフォルトの名無しさん
10/07/08 01:58:28
最近話題がない
436:デフォルトの名無しさん
10/07/08 02:29:13
くだらないネタで流れるなら止まってた方がずっといい
437:デフォルトの名無しさん
10/07/09 11:00:47
マルチスレッドと関係ないかもしれないけど、
CPUって忙しくないときどんな状態になってるんですか?
割り込み待ち状態なんですか?
それともなんらかの無限ループ状態なんですか?
438:デフォルトの名無しさん
10/07/09 12:15:51
忙しくなさ次第でいろいろ
439:デフォルトの名無しさん
10/07/09 21:49:46
>>437
ちょっと暇なときは、いっしょうけんめいだらだらしてる。
だいぶ暇なときは、夢の国へいく。
440:デフォルトの名無しさん
10/07/09 21:49:51
>>438
アイドリング状態
441:デフォルトの名無しさん
10/07/09 22:03:35
URLリンク(img.20ch.net)
442:デフォルトの名無しさん
10/07/09 23:35:26
SUZUKAサーキット
URLリンク(www.youtube.com)
443:名無しさん@そうだ選挙に行こう
10/07/10 06:31:23
>>440
それじゃ何の説明にもなってない
つーか環境次第で千差万別だから、本気でそういう情報が必要なら仕様書を当たるといい
単に何となく興味があって聞いてみた程度なら、めんどくさいから知らなくていい
仮にx86なら、暇になったらHLTかPAUSEを仕込んでおくことが多いだろうけど、そうで
ないのもあるし、単純にHLT発行すればいいって話でもないし、そもそもぶっちゃけた話、
全く知らない奴に頭っから全部説明してらんね
halt状態の休み方も何段階もある訳だし
444:デフォルトの名無しさん
10/08/12 12:18:23
>ちょっと暇なときは、いっしょうけんめいだらだらしてる。
スピンロックか
445:350
10/08/17 20:53:09
「マルチスレッド」の説明する時に「マルチタスク」の状態遷移持ち出す奴がいて、俺的には「?」なんですが、そういうのありなんですか?
446:デフォルトの名無しさん
10/08/17 21:25:38
プロセス空間が分かれていない頃の書籍でマルチタスク学んだ人なら普通じゃね?
447:デフォルトの名無しさん
10/08/17 21:34:57
>>445
大して難しい話じゃ無いし、基本だから知っておくべきだろう。
448:デフォルトの名無しさん
10/08/17 22:30:37
リアルタイムOSの「タスク」は、Unixのスレッドのようなものだったりするぞ。
449:デフォルトの名無しさん
10/08/21 13:56:10
>「マルチタスク」の状態遷移
て何ぞね
DORMANT/WAITING/RUNNINGとか言った類類の話ならタスク単体の状態だし
タスク同士の関係は非同期というのがマルチタスクの本性であるからして、
複数タスクに渡る状態など一般には規定しようがない
設計者がタスクそれぞれに明示的に同期ロジックをプログラムしたという想定で、
その詳細が明かにされた上でなら話は別だが
450:デフォルトの名無しさん
10/08/29 12:59:13
まあ、>>445は理解できなかったって言ってるんだから説明も出来ないだろう
451:デフォルトの名無しさん
10/10/01 17:29:29
あんまり理解できてないのでうんこみたいな質問申し訳ないんだけど、
スレッドが二つ(A,B)あって、
変数 int a にスレッドAがひたすら数字を入れて、スレッドBはひたすらその数字を読むだけの場合、
int aの書き込み・読み込み時にクリティカルセクション使う必要はある?
手元で試してみたら片方が読み込みオンリーの場合正常に動いたんよね
452:デフォルトの名無しさん
10/10/01 18:10:07
移植性のあるコードを書こうと思ったら必要なる。
ただハードやOS・言語・コンパイラ・ライブラリなどが想定するメモリモデル
(平たく言えばマルチスレッドでメモリがどう見えるかのルール)によっては
それで正しいケースもある。
具体的な回答が欲しいならpthread、Win32のスレッド、Javaや.NETくらいの
くくりで質問するといいよ。
453:デフォルトの名無しさん
10/10/01 18:34:06
>>451
まず、書き込まれた値が化けたりせず正常に読めるか、という点については
適切にアラインされている、CPUのワードサイズ以下の値なら、まず問題ない。
Cコンパイラにおいて、「int」として扱われる値を
Cコンパイラに配置させる場合は、まず大丈夫。
ただし、スレッドAが書き換えた後にスレッドBが読み出したとき
直前の変更が適切に反映されているかどうか、については
環境依存、というか普通は保証されない。
454:デフォルトの名無しさん
10/10/01 18:41:34
一方通行なら問題ないでしょ
455:デフォルトの名無しさん
10/10/01 18:44:58
他に受け渡すデータが一切どこにも何もなくて、ただその数字1個を渡せばいいだけなら
456:デフォルトの名無しさん
10/10/01 18:49:48
ハード依存OKということならシングルCPUのPCは
スレッドに関するほとんどの問題発生しないし正常に動くね。
457:デフォルトの名無しさん
10/10/01 18:55:25
読み出しで値を比較するときはちょっと考えないといけないかも
458:デフォルトの名無しさん
10/10/01 18:57:15
>>456
いくらなんでも、理解して無さすぎ
459:デフォルトの名無しさん
10/10/01 18:57:30
>>452
すまん、VC++で、Win32APIのCreateThread使った話だった
>>453
thx 直前の変更は特に気にしなくてもよさそう
取り扱う変数がvectorとかlistになってくるとまた違うんかな……
460:デフォルトの名無しさん
10/10/01 22:14:34
ひたすらスレッドAが書き込んでスレッドBが読み出してprintfするだけなら正しく見えるが、
例えば、イベントを受け取ってスレッドAが書き込もうとして、スレッドBは読み出すとき、
読み出された値はスレッドAが書き込こむ前か後かはCPUの気まぐれになりそうな気がする。
まぁそんな時はロックしなくてもスレッドAが書き込み終わったらスレッドBに読み込むように言えばいいけど
461:デフォルトの名無しさん
10/10/01 22:32:14
Win32での32bit読み書きはアトミックな操作だっけ?
462:デフォルトの名無しさん
10/10/01 22:38:21
Windowsならここ読んどきゃいいよ
URLリンク(msdn.microsoft.com)(VS.85).aspx
URLリンク(msdn.microsoft.com)(VS.85).aspx
463:デフォルトの名無しさん
10/10/02 04:07:15
>>461
Win32の環境じゃなくIA32とかx64の意味でじゃないの?
464:デフォルトの名無しさん
10/10/02 10:36:20
i386SXのように外部データバスが16bitのものはどうなるんだろ。
i386SXでマルチプロセッサ構成は見たことがないけどね。
465:デフォルトの名無しさん
10/10/02 10:56:16
たぶん、データが化ける可能性があると思う。
386SX以外にも、68000とか8088とかがその系統だったと思うし
今後も組み込み向けとかにそういうのが出てこないとは言い切れない。
だから、「intなら大丈夫」じゃなくて「intなら普通は大丈夫」程度。
とはいえ、組み込み向けのバス幅制限があるような環境では
マルチスレッドはともかく、
マルチプロセッサ/マルチコアはまずありえないと考えて良いんじゃないかな。
466:デフォルトの名無しさん
10/10/02 11:02:40
そもそも、lock prefix使えないはずなので、マルチプロセッサが構成出来ない。
467:デフォルトの名無しさん
10/10/02 11:03:07
386SXの32ビットR/Wや8088の16ビットR/Wは、読み書きは複数サイクルかもしれないけど、
完了するまで割込まれないんじゃなかった? 仕様書見て言ってるわけじゃないけど。
同じような構成で割込まれるプロセッサもあるかもしれないけど。
468:デフォルトの名無しさん
10/10/02 11:50:37
32bitのアクセスがアトミックであると保証されてるのはi486以降とIntelの資料に書いてある
469:デフォルトの名無しさん
10/10/02 12:09:53
>>467
割り込みは確かに発生しないから単一コアのスレッドなら問題はないが、
マルチコア・CPUの場合は問題が発生する。
470:デフォルトの名無しさん
10/10/02 12:18:00
んでi386SXのマルチプロセッサやマルチコアは実在するの?
471:デフォルトの名無しさん
10/10/02 12:46:22
SXかどうかはわからないが386のマルチプロセッサはあったらしい。
URLリンク(ja.wikipedia.org)
プロセッサレベルの割込みじゃなくて、バスの読み書きがどうかということだと思うんだけど。
472:デフォルトの名無しさん
10/10/02 12:55:16
>>471
それはi386DXだな
473:デフォルトの名無しさん
10/10/02 14:15:52
ハードのことわからんのに憶測で書くなよ
474:デフォルトの名無しさん
10/10/02 15:18:15
>>468
i386まではDMA操作なら割り込めた、CPU単体でならアトミックだったがSXでマルチプロセッサ組んだらダメだろうと思う
475:デフォルトの名無しさん
10/10/02 15:22:14
小数点付きのプログラムカウンタのあるCPUでも使ってるんかね
476:デフォルトの名無しさん
10/10/02 22:16:44
>>475
パイプラインの途中を指し示したいみたいな?
477:デフォルトの名無しさん
10/10/02 23:05:16
たぶん475は、全ての命令が1クロックで実行できると思ってる。
478:デフォルトの名無しさん
10/10/02 23:52:07
intelのは1クロックで動くんじゃないの
479:デフォルトの名無しさん
10/10/02 23:58:09
ワイヤードロジックをほぼ全体に使うようになったのは486から
480:デフォルトの名無しさん
10/10/03 00:08:11
>>467
割り込みと、トランザクションをごっちゃにしてる?
CPUの割り込みはR/Wの間に中断しないだけ。
マルチプロセッサについてはRとWが別のトランザクションなんでR/Wの間に別のプロセッサのRやWが割り込める。
この割り込みを防ぐ信号を駆動するのがインターロック命令
481:デフォルトの名無しさん
10/10/03 01:17:48
URLリンク(gcc.gnu.org)
482:デフォルトの名無しさん
10/10/03 11:49:42
読む側が、変更されない変数読んでると思われて最適化されちゃうとか無いの?
volatile付けなくても大丈夫?
483:デフォルトの名無しさん
10/10/03 13:45:17
>>482
スレッド間で共有する変数はvolatileつけておくべきだよ。
484:デフォルトの名無しさん
10/10/03 14:19:19
>>483
そんないいかげんな知識で大丈夫か?
485:デフォルトの名無しさん
10/10/03 14:31:25
馬鹿は黙れ。CPUの基本構造も知らずにプログラム組むとか笑えない。
486:デフォルトの名無しさん
10/10/03 14:33:44
>>484
完璧な解説ヨロ
487:デフォルトの名無しさん
10/10/03 14:50:17
ここ読んどけ
URLリンク(d.hatena.ne.jp)
488:デフォルトの名無しさん
10/10/03 14:58:02
>>465
> とはいえ、組み込み向けのバス幅制限があるような環境では
> マルチスレッドはともかく、
> マルチプロセッサ/マルチコアはまずありえないと考えて良いんじゃないかな。
組込み マルチコア でググレばわかるように、もはや組み込みでもマルチ
コアはありえないと言える状況ではないよ。
489:デフォルトの名無しさん
10/10/03 15:10:07
8088やi386SXみたいな内部と外部でバス幅が違うような
石を使わざるを得ない(特殊な?)状況限定の話にそんなレスされても。
490:デフォルトの名無しさん
10/10/03 16:00:49
内部と外部でバス幅が違うなんて組み込みだと今時珍しくないが
もしかしてそんなことも知らんのか?
491:デフォルトの名無しさん
10/10/03 16:58:51
ハードの事わかって書いてるわけじゃないでしょ
最適化されたときのコードの矛盾とかをハードの問題みたいに思ってるのかも
492:デフォルトの名無しさん
10/10/03 19:47:54
【OS】 Linux,W2K
【言語】 C
【実行環境】Cygwin(W2Kの場合)
【その他特記する事項】 以下の行列演算は高速化できるのでしょうか。
スレッドの意味も作り方もわかりません。
for(j=0;j<16;j++){
for(i=0;i<16;i++){
d1[j]^=GF[e1[j][i]];
d2[j]^=GF[e2[j][i]];
}
}
493:デフォルトの名無しさん
10/10/03 20:23:30
>>492
それCでコンパイルできた?
494:デフォルトの名無しさん
10/10/03 20:29:53
>>488>>490
「バス幅が違うような環境でマルチコアなんかないだろ?」と
>>465には書かれているように見えるが
おまえ、日本語は苦手か?
両方を満たしたものがめずらしくもないものなら
そう反論しろよ。別個にではなく。
495:デフォルトの名無しさん
10/10/03 20:30:43
>>492
またお前か
496:494
10/10/03 20:38:18
ちょっと書き方を変える。
>>488
「組み込みにマルチコアはありえない」などとは、どこにも書かれてない。
偉そうにしてるが、幻覚でも見たのか?
>>490
「内部と外部でバス幅が違う環境などない」などとは、誰も言ってない。
偉そうにしてるが、電波でも受け取ったか?
「内部と外部でバス幅が違うような用途でも、マルチコアが採用されつつある」
と言いたいのなら、ちゃんとそう書け。
497:デフォルトの名無しさん
10/10/03 22:28:11
> 「組み込みにマルチコアはありえない」などとは、どこにも書かれてない。
⇒ 「マルチプロセッサ/マルチコアはまずありえない」と書いてますが?
>「内部と外部でバス幅が違う環境などない」などとは、誰も言ってない。
誰もそんなことは言ってないし、誰もそれに反論なんてしてない。
むしろ、最近は珍しくないと書いてあるんだが。
偉そうにしてるが、一体誰と戦ってるんだ? (w
498: ◆0uxK91AxII
10/10/04 23:01:18
>>484
大丈夫だ、問題無い。
499:デフォルトの名無しさん
10/10/05 22:30:40
>>498
インテルは言っている、素直にインテル・スレッディング・ビルディングブロックを使えと
500:デフォルトの名無しさん
10/10/06 01:31:55
インテルは言っている、インテルはいっている
501:デフォルトの名無しさん
10/10/06 09:05:27
エルシャダイスレはここですか?
502:デフォルトの名無しさん
10/10/06 19:27:08
だめええ!入れないでえええ!インテルいれちゃだめええええええええ!!あ?
503:デフォルトの名無しさん
10/10/06 21:54:44
インテルは逝ってる
504:デフォルトの名無しさん
10/10/10 11:00:31
スタベーションを回避する方法を教えてください。
505:デフォルトの名無しさん
10/10/12 15:22:11
待ち行列の先頭にいるスレッド以外は偶然入れても待ち行列の最後に並んで前の人が終わるまで待つとか
506:デフォルトの名無しさん
10/10/12 20:17:24
>>504
A,B,Cというセマフォを取得するときどのスレッドもA,B,Cの順でセマフォを取得する。
507:デフォルトの名無しさん
10/10/13 01:49:19
【OS】WindowsXP
【言語】C++,Win32
【実行環境】VisualStudio2005
かなり基本的な質問です。
スレッドを外部から終了させたい場合、どのようにすればいいのでしょうか?
あるスレッドを常に動かしていて、ユーザーがGUIプログラムを閉じた場合に、メインスレッド側からどのように命令すればいいのかわかりません。
URLリンク(msdn.microsoft.com)
↑のようなページやググって調べると、スレッド関数側が自発的に_endthreadex関数などで終了する例はあるのですが、
終了するタイミングをスレッド関数側が知らない場合についてはあまり書かれていません。
よろしくお願いします。
508:デフォルトの名無しさん
10/10/13 02:06:21
終了するタイミングをスレッド関数側に教える仕組みがいくつかある
509:デフォルトの名無しさん
10/10/13 06:37:16
>>507
何とかしてサブスレッドに終了を伝える方法を自分で実装する。特に関数はない。
Windowsならvolatile boolかCreateEvent+SetEventでいいだろう。
510:デフォルトの名無しさん
10/10/14 04:23:26
いいか、お前らTerminateThreadは使うなよ!使うな!絶対に使うなよ!
511:デフォルトの名無しさん
10/10/14 07:47:26
kill -KILLですね、わかります。
512:デフォルトの名無しさん
10/10/14 22:51:22
TerminateThread = ハングしろ に近いからねぇ
.Netとかだとそもそも抹消されてるが。Suspendも割と個人的に怖いな
513:デフォルトの名無しさん
10/10/14 22:52:08
TerminateThreadに頼ったプログラムは死んでいいけど、
バグがあってサブスレッドが応答しなくなった時の万が一のためにTerminateThreadするのは
いーんでないの
514:デフォルトの名無しさん
10/10/14 23:08:49
つーかスレッドの終了待ちでWaitFor*Objectしてタイムアウトしたら
TerminateThreadってのは普通だろ
515:デフォルトの名無しさん
10/10/14 23:23:24
そりはバグなので速やかにアプリケーションを終了すべきでは?
少なくとも普通じゃない。
516:デフォルトの名無しさん
10/10/14 23:43:40
>>510
別に使っても問題ないよ。
DllMainのデタッチスレッドさえちゃんと実装されていれば何も問題はない。
517:デフォルトの名無しさん
10/10/14 23:58:39
Vistaより前がターゲットに入るなら「何も問題ない」は無いわ
DllMainがどう頑張ろうと関係無い
518:デフォルトの名無しさん
10/10/15 00:15:38
>>516
DllMainはコールバックされないってちゃんと書いてあるのにどういうコードを書くつもりなのか聞きたい
519: ◆0uxK91AxII
10/10/15 04:13:54
TerminateThreadするくらいならExitProcessで止めを刺す。
520:デフォルトの名無しさん
10/10/15 04:18:38
TerminateThreadなんて使う必要性あるの?
521:デフォルトの名無しさん
10/10/15 06:53:29
サブスレッドの確保したメモリとかソケットとかDB接続とかその他もろもろのハンドル
はどうするつもりだよ。
あとミューテックスをロックしたまま暴走した場合とか開放されるんだっけ?
問題ありすぎ
522:デフォルトの名無しさん
10/10/15 23:13:04
>>514
ないない
523:デフォルトの名無しさん
10/10/15 23:13:49
>>519
そのほうがごみが残らなくていいな
524:デフォルトの名無しさん
10/12/19 17:17:41
printfはどういうレベルでスレッドセーフじゃないんでしょうか
525:デフォルトの名無しさん
10/12/19 17:19:00
間違えた、sprintfです
526:デフォルトの名無しさん
10/12/19 17:22:56
書込み先のことかな?
527:デフォルトの名無しさん
10/12/19 17:24:15
処理系によるんじゃないでしょうか
528:デフォルトの名無しさん
10/12/19 17:30:04
MT-Safe ってどういう意味?
529:デフォルトの名無しさん
10/12/19 17:30:49
複数のスレッドで安全という意味
530:デフォルトの名無しさん
10/12/19 17:32:51
>>527
POSIXというか、ぶっちゃけLinuxの標準ライブラリstdioでならどうでしょうか。
ここまで範囲限定したらスレチになんのかな?
531:デフォルトの名無しさん
10/12/19 17:35:10
POSIXのstdioで _unlocked が付いてないものはスレッドセーフです
532:デフォルトの名無しさん
10/12/19 19:46:28
つまりprintfはスレッドセーフってことか。ありがとう!
533:デフォルトの名無しさん
10/12/19 21:15:28
関数がってことで、使い方間違えると...
534:デフォルトの名無しさん
10/12/19 23:13:56
まぁ想像するだけでもprintfは外部に出力するからロックとか色々してるのは分かる
printfしたらバグが起こらなくなったとかで原因がスレッド絡みとかよくある
んでprintfで起こらなくなるから放置とかマジ勘弁してくださいorz
535:デフォルトの名無しさん
10/12/24 00:47:37
スレッドセーフなメモリの読み書きについて勉強しているのですが、情報が少なく捗りません。
メモリへの同時アクセスによるデータ破壊は、書き込み時にのみ起こると認識しているのですが、正しいでしょうか?
・二つのスレッドが一つの変数を書き換えるとき
→データが破壊される場合がある。
・一つのスレッドが一つの変数を書き換え、別のスレッドがその変数を読み込むとき
→書き込みは問題なく行われる。
→読み込みは、書き換え途中のデータを読み込む場合がある。
・二つのスレッドが一つの変数を読み込むとき
→問題なし。
536:デフォルトの名無しさん
10/12/24 01:06:26
書き込まないものを読み込むことにどんな意味があるのだろうか
537:デフォルトの名無しさん
10/12/24 01:10:53
const 定数ですね
538:デフォルトの名無しさん
10/12/24 01:43:18
>>535
いずれも正しい。
539:デフォルトの名無しさん
10/12/24 06:02:20
ありがとうございます。理解が深まりました。
540:デフォルトの名無しさん
10/12/24 09:17:21
>>535
> ・二つのスレッドが一つの変数を書き換えるとき
> →データが破壊される場合がある。
データの破壊とは何ぞや?単に後から書いたデータが残る。それだけの話。
541:デフォルトの名無しさん
10/12/24 09:53:16
それぞれの書き込みがアトミックならね。
32ビットマシンで64ビットの書き込みとか、アトミックでない場合、破壊が起こるかもしれない。
542:デフォルトの名無しさん
10/12/24 15:07:31
>>540
配列だって、立派な配列変数だぜ。
文字列型変数もあるしな。
543:540
10/12/24 15:52:35
そうだった、最近のデータはでかいんだな。
組み込み系のスレ見た後だったから頭がアセンブラレベルになってた。
失礼。
俺はどっちにしてもミューテックスかクリティカルセクションで排他しておくけど。
544:デフォルトの名無しさん
10/12/24 17:17:54
同時アクセス時の挙動なんてCPUの仕様次第だろ
同時読込なら安全なんて確証は無い
545:デフォルトの名無しさん
10/12/24 17:20:04
データが小さければ読み書きのキャッシュ問題とか無視できるが、
今はふつうに扱う標準データが大きいからなあ。プログラミングも大変だ。
546:デフォルトの名無しさん
10/12/24 17:20:27
アホ発見
547:デフォルトの名無しさん
10/12/24 17:30:42
同時読込なら安全なんて確証は無い・・・
ということは同じ関数を同時に実行するとまずい場合があるってことか
同じ関数を同時に実行すると同じ命令列を同時に読込むことになるもんな
548:デフォルトの名無しさん
10/12/25 20:23:56
言語仕様じゃなくハードウェア仕様だと理解してればいい
大丈夫かどうかを言語仕様で調べても守備範囲外のことで規定されてないから無駄
549:デフォルトの名無しさん
10/12/25 20:28:39
いや失礼、言語仕様で規定されてる物もあるか
550:デフォルトの名無しさん
10/12/26 16:17:56
printfがスレッドセーフじゃないのはわかるけど
どうしてsprintfがスレッドセーフではないのはなぜ?
551:デフォルトの名無しさん
10/12/26 16:24:32
>>550
内部にスタテックバッファーを持ってるかも。
552:デフォルトの名無しさん
10/12/26 16:54:42
>>551
まじか・・・だらしのないやつだなsprintfも・・・
553:デフォルトの名無しさん
10/12/26 17:45:40
おまえが使ってるライブラリを実装したところに聞けよ
554:デフォルトの名無しさん
10/12/26 18:09:36
sprintfがスレッドアンセーフってのはどこ情報?
555:デフォルトの名無しさん
10/12/26 19:50:50
あとだしで申し訳ないがライブラリはglibcです
>>554
URLリンク(slashcolon.com)
URLリンク(www.kmonos.net)
Dでスレッドセーフにしました=Cだとスレッドセーフちがう
と解釈しました
ていうか、そもそもprintfがスレッドセーフだという情報がない。
不明なうちはアンセーフ扱いするのが俺のジャスティス
556:デフォルトの名無しさん
10/12/26 20:00:44
なるほど
確かに
557:デフォルトの名無しさん
10/12/26 20:13:26
それ英語版見たらスレッドセーフなんてどこにも書いてないぞ・・・
> writefln() improves on printf() by being type-aware and type-safe:
誤訳じゃないのか
558:デフォルトの名無しさん
10/12/26 20:16:54
URLリンク(stackoverflow.com)
適当にぐぐったけどglibcはスレッドセーフとか書いてるような感じ
559:デフォルトの名無しさん
10/12/27 11:09:50
へえ
560:デフォルトの名無しさん
10/12/27 14:34:33
探しても「セーフだろう」「たぶんセーフ」ばっかりしか出てこない
むずむずするなぁ
561:デフォルトの名無しさん
10/12/27 15:03:50
IEEE Std 1003.1-2001の定義では、例外的にアンセーフで良いとされているもの以外は
スレッドセーフ。
URLリンク(pubs.opengroup.org)
562:デフォルトの名無しさん
10/12/28 19:19:26
過去スレ全部はみれなかったんだけど、マルチスレッド関連の良書をまとめてみる。
この他にこれがいいとかあったり、これ駄目とかあったら教えて。
[一般]
並行コンピューティング技法 ―実践マルチコア/マルチスレッドプログラミング
The Art of Multiprocessor Programming 並行プログラミングの原理から実践まで
増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編
[java]
Javaスレッドプログラミング―並列オブジェクト指向プログラミングの設計原理 (OO SELECTION)
Concurrency: State Models and Java Programs 2edition
Java並行処理プログラミング ―その「基盤」と「最新API」を究める
[windows]
Win32 マルチスレッド プログラミング
Advanced Windows 第5版 上
Advanced Windows 第5版 下
[Unix]
POSIXスレッドプログラミング
563:デフォルトの名無しさん
10/12/31 19:52:51
[C++]
インテルスレッディング・ビルディング・ブロック
主にこのライブラリの使い方だが、
他にもスレッド管理の考え方が載ってる。まぁオープンソースなので見れるのだけど
564:デフォルトの名無しさん
11/01/03 21:56:27
ありがとうございます。C++の良書をあまり知らないので助かります。
565:デフォルトの名無しさん
11/01/15 09:14:58
concurrent hashmapのC++実装って
なんでないの?
566:デフォルトの名無しさん
11/01/15 09:49:16
>>565
キミのためにお取り置きしてある。
567:デフォルトの名無しさん
11/01/15 10:31:02
>>566
並列mapでいいから実装ないの?
C++って並列コンテナないから何もできないよね
568:デフォルトの名無しさん
11/01/15 18:21:33
>>567
キミが作るだろうと思って残しておいた。
569:デフォルトの名無しさん
11/01/16 11:14:37
>>567
俺のところにはある。
570:デフォルトの名無しさん
11/01/16 11:28:44
C/C++はアセンブラと高級言語の間みたいな位置だからな
言語そのものを作るとか、OSを作るとか、リソースの厳しい組み込み系で作るとか、
そういう用途じゃないなら別に強力な言語ではない
ネイティブのCPUの挙動を理解しないとC/C++の有用性は半減すると思われ
571:デフォルトの名無しさん
11/01/25 23:02:03
すみません、spin-lockをしている間にCPUの使用率を下げる方法を知っている方はいますか?
調べてみると、rep;nop命令やSSEのpause命令をがそれに該当するように思えるのですが、
使ってみても何ら変わりませんでした。
スピンロックつかっわないとは思うんだけど。
自作のスレッドバリア関数(自作のspin_lock)を作って、
たとえば、
if(threadnum=5) sleep(10);
my_barirrer();
とするとスレッド5を待っている間は5以外のCPU使用率が100%近くなってしまいます。
それに対してOpenMP使った場合では、
if(threadnum=5) sleep(10);
#paragma omp barirrer
だと待っている間はCPU使用率は殆ど変わりません。
ちなみに自作のspinlockは下記のような感じです。
if(thread_num == 0)
{
asm volatile(
"Loop1:\n\t\t"
"movl (%0), %%eax\n\t\t"
"movl (%1), %%ebx\n\t\t"
"lfence\n\t\t"
"cmpl %%ebx, %%eax\n\t\t"
"rep;nop\n\t\t"
"jne Loop1\n\t\t"
:
:"r"(&lock->sync), "r"(&lock->maxthreads)
:"memory","%eax","%ebx"
);
というか、これって間抜けですかね?
572:デフォルトの名無しさん
11/01/25 23:10:46
自前でタスク切換えみたいなことするしか
573:デフォルトの名無しさん
11/01/25 23:15:42
>>571
>>369
574:デフォルトの名無しさん
11/01/25 23:24:51
>>573
お前友達いないだろ
575:デフォルトの名無しさん
11/01/25 23:34:47
>>571
Sleepさせりゃいいんじゃね。
576:デフォルトの名無しさん
11/01/25 23:44:45
割り込みでしか切り替わらないコードで使用率下げたいというのが
577:デフォルトの名無しさん
11/01/28 22:22:30
さむいな(´・ω・`)
578:デフォルトの名無しさん
11/01/28 22:43:23
寒稲
579:デフォルトの名無しさん
11/01/31 22:10:29
>>571
CPU使用率が100%じゃないロックなんて、スピンロックとは認めない。
580:デフォルトの名無しさん
11/02/01 00:53:40
そもそも100%じゃないってことはコンテキストスイッチしてるってことになるでしょ?
何のためのスピンロックなのよあり得ない。
581:デフォルトの名無しさん
11/02/01 10:50:42
スリープロックのループもスピン扱いすることもあるから何とも
582:デフォルトの名無しさん
11/04/04 19:37:25.20
ちょっと聞いていい?
以下のコードでnotifyAllされたらどうなるのって質問
void A()
synchronized(Lock){
if(List.size() == 0){
try{ Lock.wait(); }(Exception e){}
}
//以下処理続く
}
}
このコードで複数のスレッドが待ち状態だったらnotifyAllとき再度Lockを取りに行ってくれるの?
もし、そうだったとしたら。
結局はnotifyで1つのスレッドのみ動かすってのと同じことになるの?
それとも再起処理的に以下のようにしなきゃだめ?
void A()
synchronized(Lock){
if(List.size() == 0){
try{ Lock.wait(); }(Exception e){}
A(); ←ここでさらに再帰的に同じメソッドを呼び出す
}
//以下処理続く
}
}
おしえてエロイひと。。。
583:デフォルトの名無しさん
11/04/04 19:47:38.94
>>582
notifyAll を呼ぶと、wait してたスレッドはすべて起きて、 Lock を取りに行く
どうせみんなすぐには取れないから Lock 待ち状態になるが、すでに wait からは外れてるので、 Lock を取れた順にすべてのスレッドが動き出す
notify の場合は、wait してたスレッドのうちひとつだけが起きて Lock を取りに行く
他のスレッドは、その後 Lock が空いても、眠ったまま起きない
wait はふつう再帰じゃなくて while にする
synchronized (Lock) {
while (List.size() == 0) {
Lock.wait();
}
}
waitは、notifyされてなくても間違って起きることがあるらしいので、このように書くべきこととされている
584:デフォルトの名無しさん
11/04/04 20:17:38.60
>notifyAll を呼ぶと、wait してたスレッドはすべて起きて、 Lock を取りに行く
ということはnotifyAllでそのまま下に処理が流れていくんじゃなくて
再度 synchronized(Lock){ ←この部分に処理が戻ってくるイメージなんですかね?
別のメソッド内の以下のようなコードでnotifyAllをかけようと思ってたんだけど、
ちゃんとnumの個数分以上のスレッドは再度、wait状態に入ってくれるのか心配でした
for(int i = 0 ; i < num ; i++){
List.add(object);
}
Lock.notifyAll();
それと。
while (List.size() == 0) {
Lock.wait();
}
これしなきゃいけないんですね。Javadoc見てきました。
>>583 ありがとー。
585:デフォルトの名無しさん
11/04/04 21:55:04.24
>>584
synchronized のところまで戻るわけじゃなく、synchronized の中にいるまま、 wait のところで、
Lock をいったん解放、おやすみなサイして、起きたら元通りに取りにいく
wait は synchronized の中でありながら Lock を手放している特殊な場所
notifyAll を呼んだ側のスレッドは、notifyAll を呼んだあとそのまま下に流れていく
というのも、notifyAll を呼んだ時点では Lock は notifyAll 側のスレッドが握ってるので (synchronized 中のはず)、
wait 側のスレッドは起きるけれども、Lock を取れない
notifyAll 側が synchronized から抜けるなりして Lock を解放すると、wait 側が Lock を取って動き出せるようになる