[過去ログ] 【初心者歓迎】C/C++室 Ver.106【環境依存OK】 (1002レス)
1-

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
654
(1): 2021/04/25(日)11:04 ID:vJWG11Gh(5/7) AAS
>>653
「初期化しているコード」を載せる際、ImageWidth, ImageHeightとの
値の関係が分かるようにしてほしい。
要は、ちゃんとバッファの範囲内に読み書きが収まっているかどうかが知りたい。
655
(1): 2021/04/25(日)11:19 ID:vJWG11Gh(6/7) AAS
>>652
例えば、pPxの指しているメモリーブロックのバイトサイズが、
Pitch * ImageHeight * (pPx の 1 要素当りのバイト数)
以上に、pSrcBufの指しているメモリーブロックのバイトサイズが、
ImageWidth * ImageHeight * 4
以上になっていることが重要。
656
(1): 2021/04/25(日)11:46 ID:vJWG11Gh(7/7) AAS
そういえば、pSrcBufを((DWORD *)pSrcBuf)のようにキャストしてから使っている
ことも気になる。
pSrcBuf = new DWORD [ImageWidth * ImageHeight]
ではなく、
pSrcBuf = new BYTE [ImageWidth * ImageHeight * 4]
などとしているのだろうか。
657: 636 2021/04/25(日)12:16 ID:sRfn5IZk(6/11) AAS
>>653-656
void *pSrcBuf;
LONG Pitch;
pPxは、16bitの時がWORD*で32bitの時がDWORD*
という感じになってた。

初期化の部分がかなり複雑で結構辿って調べる必要があるんだよね…
でも思うのは初期化は、16bitと32bit大体同じで違うのはpPxの型くらいで
それで>>650の32bitのコードだと全然遅くならないから
>>651の16bitのコードの部分自体が何か変だったのかなと思ったんだけど
ここ自体は大丈夫なのかな?
658
(1): 2021/04/25(日)13:26 ID:QOuShU0Z(1/2) AAS
そもそも遅くなるって何分が何分になるん?
100分が103分ならそんなもんじゃね?
としか思えないし
659
(1): 2021/04/25(日)13:48 ID:sRfn5IZk(7/11) AAS
>>658
それが30秒が2分とか3分とかになっちゃって。
660
(1): 2021/04/25(日)14:01 ID:9Nm1id/y(1/4) AAS
>>659
それだとせいぜい6倍くらいだね。
>>650>>651 だと 6倍くらいの差が出るのは当然だよ。
661
(3): 2021/04/25(日)14:37 ID:sRfn5IZk(8/11) AAS
>>660
いやそうじゃなくて、>>636のダミーコードを入れると
何故か速い速度になって、それを取り除くと遅くなってしまう感じ。
普通にコード書いてても関係ない部分を追加したりすると遅くなったり
速くなったりするからおかしいなと思ってて。
662
(1): 2021/04/25(日)14:41 ID:9Nm1id/y(2/4) AAS
>>661
なるほど。では、
>初期化の部分がかなり複雑で結構辿って調べる必要があるんだよね…
であったとしても、原因を特定するには、少なくともまずそこを丹念に
調べる必要がある。
663
(1): 2021/04/25(日)14:41 ID:QOuShU0Z(2/2) AAS
>>661
とりあえず遅いコードと速いコードを晒してよ
バッファーオーバーランで制御変数壊してるとかあるかも知れんし
664
(1): 2021/04/25(日)14:45 ID:9Nm1id/y(3/4) AAS
>>661
そういえば、速い時でも30秒もかかっていることはとても気になる。
>>650 のコードだとどれくらいの時間になるの?
経験と勘で言えば、そのような平易なコードで30秒も掛かって、
時と場合により3分もかかるという現象が起きる場合、キャッシュ
が乱れている可能性がある。
もしかして、どこかで極端にメモリーをランダムアクセスしてない?
巨大なメモリーの中を、極端に不連続な場所をあっちこっちアクセスすると
キャッシュが聞きにくくなって、急激に遅くなることがある。
665
(2): 2021/04/25(日)14:57 ID:sRfn5IZk(9/11) AAS
>>662
確かにそこは念入りに調べる必要がありますね。
>>663
それが本当に>>636をまったく関係ない部分に入れるだけで
速くなったりしてて。普通にコード書いてまったく関係ないところ追加したりすると
速くなったり遅くなったりするんだよね。一旦速くなったら弄らない限り遅くなる事はなくて
逆に一旦遅くなったら弄らない限り速くなったりする事はない感じ。
>>664
読み込んでメモリ操作する部分自体はかなり多い数をやってるので
20〜30秒くらいかかる時もある感じ。
省2
666
(1): 2021/04/25(日)15:04 ID:9Nm1id/y(4/4) AAS
>>665
>読み込んでメモリ操作する部分自体はかなり多い数をやってるので
>20〜30秒くらいかかる時もある感じ。
話を総合すると、
>>650 のコードが、「20〜30秒くらいかかる」が、
>>651 のコードが、速い時には「30秒」
ということになるが、コードを見る限り、651のコードは650の
コードの10倍以上かかっても不思議ではないコードになっているので、
この速度差はむしろ、少な過ぎる。
むしろ、>>651のコードは「3分」かかっている方が、
省1
667
(1): 2021/04/25(日)15:13 ID:CFgRAQQ/(1) AAS
読込とか細かいメモリー確保とかコードに無いこと言われてもエスパーじゃないのでどうしょうもないな
悪いけど情報出せないなら他でやってくれ
668
(1): 2021/04/25(日)15:19 ID:sRfn5IZk(10/11) AAS
>>666
今チェックしたら650の方が少し速かったですw
650が12秒くらいで、651が22秒くらいでした
これが速い場合で、651が遅い場合は2分くらいでした。
650は遅くなることがないです。

>>667
ほんとうにそうですね。
とりあえず晒した所が大丈夫なら
他の部分は自分で調べてみようと思います。
669
(1): 2021/04/25(日)15:45 ID:S2tV53BX(1/2) AAS
>>668
>今チェックしたら650の方が少し速かったですw
>650が12秒くらいで、651が22秒くらいでした
>これが速い場合で、651が遅い場合は2分くらいでした。
>650は遅くなることがないです。

これだけでも重要なことが分かる。以後は、処理時間に関する(数学的な)定量的な話になる。
まず、650と651の速度差が1.8倍程度しかないことからすると、
pSrcBuf と pPx の読み書きに相当時間が掛かっていることを示唆している。
650と651のソースを比較した時、計算部分の処理がとても増加しているが、
読み書きはキャッシュまで考慮すると、650と651で差が出ない。
省14
670
(1): 2021/04/25(日)16:25 ID:sRfn5IZk(11/11) AAS
>>669
細かい分析ありがとう。
だとしたら>>636のダミーを入れると速くなるのも
そのキャッシュの原因に何か関係してるのかな?
でも今まで>>665でも書いたように一旦遅くなったら
遅くなったままで、速くなったら速くなったままなんだよね… コード弄らない限り。
もしかすると何か条件が重なればコードを弄らなくても遅くなったり
速くなったりすることもあるのかもしれないけど。今のところは確認出来てない感じ。
671
(1): 2021/04/25(日)16:32 ID:S2tV53BX(2/2) AAS
>>670
それより、650のコードで12秒も掛かっていることにかなり違和感を覚える。
ImageWidth が、ImageHeight が 2000 位までなら、4*10^6 ピクセルくらいで、
32BIT RGBカラーだとしても16MB位。
いまのCPUだと、>>650のコードくらいで12秒も掛かるはずは無い。
大雑多な予測だと、3.0GHzのCPUで、10(ms)くらいまでのはず。
ImageWidth や ImageHeight の値はいくらくらいになってる?
672
(1): 2021/04/25(日)17:04 ID:/0G3TNx0(1) AAS
650は最適化で X も x も同じ値で遷移していくし内側のループは
memcpy 相当のブロック転送におきかわりそうだけど
673
(1): 2021/04/25(日)20:18 ID:j6IXZwA/(2/2) AAS
650使えば遅くならないならいったん解決?
674
(2): 2021/04/26(月)01:18 ID:0cli3R6k(1/4) AAS
>>671
大きな画像(2048*2048)とかを結構読み込んでて。
読み込み処理自体は他の部分もあるのでそのくらいになってしまってる感じ。
>>672-673
一応は650にすれば何の異常もなくとても速く動作はするんだけど
出来れば原因が知りたいと思ってて。難しいならもうあきらめるけど。
675: 2021/04/26(月)01:51 ID:u7NjNSbC(1/3) AAS
>>674
ファイルから読み込んでるらしいけど、fseek をループの中で多数回使うと
使わない場合と比べて劇的に遅くなるけど、seek 系の関数は使ってない?
676: 2021/04/26(月)02:03 ID:+l9LtKe6(1) AAS
ファイル読み込みの部分でHDDキャッシュがかかってるかどうかだったり
よくある話
677
(3): 636 2021/04/26(月)02:36 ID:0cli3R6k(2/4) AAS
色々と試行錯誤してたら
>>651のコードのこの部分を
for(int x = 0; x < ImageWidth; ++x){
このように書き換えたら普通に速くなったw
for(int x = 0; x < ImageWidth / 1.0f; ++x){

なんか最適化が効いたり効かなかったりみたいな差に感じてしまう。
そういう原因なのかな?
678
(1): 2021/04/26(月)02:37 ID:u7NjNSbC(2/3) AAS
>>674
2048 * 2048 ドットの画像だとベタデータにしたとき16MBになってしまうので、
それを沢山読み込むとメモリー不足になり仮想記憶が働いてしまっている可能性も
有るかも知れない。どれくらいの枚数読んでいるか知らないのでなんとも
言えないけど。
679
(1): 2021/04/26(月)02:39 ID:u7NjNSbC(3/3) AAS
>>677
使ってるのはVisualStudioのようだけど、速度を測定する時には、ちゃんと
Release版にして最適化は有効にしてる?
DebugPrintを使っているなら最適化はOFFになってるのでは?
680: 2021/04/26(月)02:43 ID:0cli3R6k(3/4) AAS
>>678
でも>>677の修正で速度が劇的に変化するのはなんでなんだろう?
>>679
Releaseで調べてるよ。OutputDebugStringはReleaseモードでも使えるので。
681: 2021/04/26(月)02:46 ID:0cli3R6k(4/4) AAS
>>677の修正をしたあと、>>636のダミーコードを
追加したらなんと今度は遅くなったwwなんでだ?w

>>636のダミーコードだけ追加したら速くなって
ダミーコードを削除すると遅くなる
その遅くなった状態で>>677の修正をすると速くなる
その速くなった状態で>>636のダミーコードを入れると
今度は遅くなるww
682
(1): 2021/04/27(火)02:43 ID:qV+SOSDm(1) AAS
状況から察するに、おそらく君が見ている部分じゃない
どこかに根本的な問題がある、という気がする
なんとなくだけど、バッファオーバラン系のような気がする
683: 2021/04/27(火)05:25 ID:Vf/GSwOl(1) AAS
>>682
どこかに問題がありそうですよね。
バッファオーバラン系は問題あっても動いてしまう事があるから怖いですね。
地道に調べて行くことにします。
684
(1): 2021/04/27(火)11:47 ID:V9b4VlmB(1) AAS
それより、12秒間も大量のメモリーを使う状態でCPUがフルパワー状態になっている
とすれば、フル・キャッシュ汚染してる可能性がある。
フル・キャッシュ汚染すると、その後しばらくの間、キャッシュを取り戻すために
速度が不安定になるから、説明可能。
685
(1): 2021/04/27(火)12:52 ID:cPrICHbO(1) AAS
Meltdowm や Spector 対策のパッチの影響とか?
特定のパターンのメモリアクセスに対して例えばなんかのトラップが働いてキャッシュをクリアし、ダミーコード入れるとそのパターンが崩れてそういう処理が入らないとか。
686
(1): 2021/04/28(水)02:54 ID:XgRH6ChF(1/2) AAS
>>684-685
みなさんありがとうございます。
色々な問題が考えられそうですね。参考になります。
もう少しコード弄りながら挙動を調べて行きたいと思います。
687
(2): 2021/04/28(水)04:32 ID:v8E9sca8(1) AAS
>>686
なお、y方向に関して、メモリーを上下逆さまに読んでいっているところがあるが、
本当はそういうのはDDR-Memoryやキャッシュと余り相性が良くない。
しょうがないけれども。
それでも、x方向には「順方向」に読んでいるからまだなんとかなっている。
完全にメモリーを逆方向に読んだりすると、低速化の原因になる。
この場合には難しいが、なるべくならメモリーは順方向にアクセスした方が
速くなる。DDR-MemoryはBurst転送が基本なので。
キャッシュに乗っていれば、逆方向でもなんとかなるが、キャッシュから
外れると、DDR-MemoryのBurst転送とは逆方向にアクセスするのは
省1
688: 2021/04/28(水)10:42 ID:XgRH6ChF(2/2) AAS
>>687
そういう問題もあるんですね。とても詳しくて勉強になります。
ありがとうございます!
689
(2): 2021/04/28(水)11:32 ID:oswWyFbg(1) AAS
>>687
読み書き方向が逆になるなら、読む方を順方向にすると良さそうだと思うけどどう思う?
690: 2021/04/28(水)13:14 ID:WdoV9Bq9(1/2) AAS
>>689
コンパイラのくせに生意気だぞ
691: 2021/04/28(水)13:16 ID:jQpDsyge(1) AAS
>>689
実は昨日の夜から、俺もそう思ってた。
今は、
読む方が逆方向で、書く方が順方向になってしまっているが
読む方を順方向に、書く方を逆方向にした方が DDR-SDRAM や キャッシュの
仕組みから行って速くなる可能性が高い。
692: 2021/04/28(水)14:04 ID:4fcF+gv5(1) AAS
Windows の bitmap で ファイル中の配置や CreateDIBSection() で戻ってくるメモリの配置だな
デフォで bottom - up の方向 カメラのフレームとかは top - down な方向

ん?メモリ操作なコードだけど実はメモリマップドファイルだったりして
693: 2021/04/28(水)15:30 ID:WdoV9Bq9(2/2) AAS
走査線と描画が重なったらチラツキが激しくなるから下から描いていくんだよ
694
(2): 2021/06/14(月)15:32 ID:TE2ntQhj(1) AAS
for(int a=0; ...; ...){...} とかはループ内だけのスコープで int a が使えるのに

int a;
while(a){...}
とか
int a;
do{...}while(a);
とかは
while(int a=...){...} ←これだけはOK?
とか
do{...}while(int a=...);
省3
695: 2021/06/14(月)15:40 ID:peg/OyGg(1) AAS
do{...}while(int a=...);  宣言より前に変数を使用する
do{int a; ...}while(a);  スコープの外に変数を持ち出す
696
(1): はちみつ餃子 ◆8X2XSCHEME 2021/06/14(月)17:56 ID:fvxG9/iR(1) AAS
>>694
C/C++ の理屈では波括弧の部分は繰り返しの構文 (do や while) の一部ではない。
たとえば while の文法は
while ( expression ) statement
というように定義されていて、 statement ってのは要するに文をひとつ書けるってことね。
で、 statement として複文 (波括弧によって複数の文をひとつにまとめたブロック) もありうるってことになってる。
そんでもってブロックの先頭で宣言された変数のスコープに関するルールはブロックのほうに書かれていて、
繰り返しの構文のときだけ特別扱いということは出来んのだわ。

> while(int a=...){...} ←これだけはOK?

これは C++ では良いけど C では駄目
697: 2021/06/14(月)18:58 ID:HtMoZ8Hn(1) AAS
小さいスコープの中だけで使う自動変数だってんで
特に if や for 等なく いきなりカラス括弧開いて変数宣言することがままある
698: 2021/06/14(月)21:48 ID:OzvaLd6A(1) AAS
C++ってOSレイヤで差異が有るファイルシステムの事を考慮せずにプログラムを書ける済む仕組みって組み込まれてるの?
699: 2021/06/14(月)21:53 ID:VOy4fGQR(1) AAS
標準ライブラリに含まれるファイルシステムライブラリでできる範囲の操作なら差異は出にくいと思うけど
700
(1): 2021/06/14(月)22:00 ID:eQ9/Z+Eb(1) AAS
>>694,696
C++でもwhileの判定式中の宣言は毎回新しくなるんで、使いみち思いつかん。
while(int i=10) { i--; } は、無限ループになる。

できるとしたら、処理が終わったらすぐに始末したいobjに対して、
{ myclass obj(); while(obj) { obj.some_op(); } }
(obj は operator bool() とか実装してる前提)
が、
while(auto obj = myclass()) { obj.some_op(); }
こんな風にかけてちょっと{}がスッキリするくらい?(実際はobjが毎度構築される)
701: 2021/06/14(月)23:04 ID:wv1U8ajF(1) AAS
カラス括弧!
初めて見た!
702: 2021/06/15(火)08:13 ID:4rRZmg7L(1) AAS
>>700
まあ while(...){} は for(; ...;){} で書けるしメリットないかな
ただ
do{ int a = …; }while(a); の方は書けたら嬉しいな
使用頻度は低いけど
703: 2021/06/15(火)10:57 ID:5dh+WKsO(1) AAS
do は do .. while(0) のパターンしか使わないな。
704: 2021/06/17(木)23:23 ID:Gx3mnqFH(1) AAS
break用なら switch(0)default:{...} っしょ?
705: 2021/06/18(金)08:43 ID:R4m5mk7U(1/2) AAS
それdoよりどういうメリットある?
わざわざdefault:書かないとならないしインデント深くなりそうだし。
706
(1): 2021/06/18(金)11:21 ID:FZUuAAIq(1) AAS
マクロで展開するならインデントは無視できる
707: 2021/06/18(金)11:50 ID:7Huy+AZL(1/2) AAS
do{}while(0) は最後に ; 書く前提だし矛盾ないけど
switch(0)default:{...} は ; の扱いの困らない?
708: 2021/06/18(金)11:55 ID:AVf6Ht59(1) AAS
for (int i = 0; i < 1; i++)
709: 2021/06/18(金)12:32 ID:6AzE04jr(1) AAS
{ } 内スコープからの脱出で break; 使いたいってのと
マクロで見た目関数向けな #define foo(arg) do { なんちゃらかんちゃら } while(0)

do { } while(0) は両立できるけど switch(0)default:{} で後者は怪しげ

if (<condition>) foo(arg); else <elsecase>; とかが
710
(1): 2021/06/18(金)13:25 ID:7Huy+AZL(2/2) AAS
while(1){
...
break; // } の直前
}
で良いと思う
711: 2021/06/18(金)14:27 ID:tn5JYHw4(1) AAS
それどういう意図があんの?
処理は結局1回
スコープだけじゃダメなん?
712: 2021/06/18(金)14:44 ID:tzOvIsZE(1) AAS
>>710
お前が良いと思うなら使えばいいと思うが俺には無駄なbreakが必要なのはダサいと思うから do { ... } while(0); にするわ
713: 2021/06/18(金)20:29 ID:R4m5mk7U(2/2) AAS
>>706
マクロはフォーマッタでの扱いが定まらんから制御構造では使いたくないのよな。
セミコロンで終端しておかないとインデントがおかしくなるとか、後続に開きブレースを置くと
やっぱりインデントが変になるとか。
714: 2021/06/19(土)12:53 ID:EDF+B3Dq(1) AAS
#define breakblock switch(0)defalut:
でいいやん
できないとか怪しげとか意味不明
マクロ化する必然性がそもそもわかんないけど
715: 2021/06/19(土)13:08 ID:AhXAE8oj(1/2) AAS
そこまでして switch(0) 使う理由がよくわからん。
do while(0) と比べてどういうところが良いの?
716: 2021/06/19(土)13:21 ID:ylfkd6bV(1) AAS
マクロの例でもわかるように波括弧を単独で使える
変な処理が始まってんの一目瞭然
continueもgotoで(goto使わない別ルーチン探せよw

#define breakblock(a) uniqelonglongprefix##a:switch(0)default:
#define bbcontinue(a) goto uniqlonglongprefix##a
717: 2021/06/19(土)14:04 ID:AhXAE8oj(2/2) AAS
>マクロの例でもわかるように波括弧を単独で使える

ようは末尾に while(0); を書かなきゃならないのが嫌ってことかな。
わからんでもないが、自分はマクロや default: より気にならないからいいや。
718: 2021/06/19(土)16:30 ID:8gjebq3e(1) AAS
#define foo(arg) switch(0)default:{ なんとかかんとか }

これはキモイ
719: 2021/06/20(日)18:26 ID:3hmKhJNO(1) AAS
でもその構文はdefineで置き換え前提で使ってるとしか思えない
720: 2021/06/20(日)19:15 ID:XoXh1cqB(1) AAS
goto書くと死んじゃう人は大変だなぁ
Dijkstraもそこまでは言ってないらしいぞ
721: 2021/06/20(日)22:56 ID:R7oo70Ox(1) AAS
ナンチャラカンチャラの人のdefine使用意図が無意味すぎてどうもc言語エアプなんじゃないかと疑う
722: 2021/06/21(月)16:42 ID:iJjBc6fp(1) AAS
switchのやつは最後にbreakかfall throughってコメント書いとかないと文句言うチェッカとかありそう
723: 2021/06/29(火)11:07 ID:HA4DrIsJ(1) AAS
do {
int a;
:
} while(a);



for(int a;;) {
:
if(!a) break;
}

でいいんじゃない?
724
(4): 2021/07/05(月)16:13 ID:3/iVgePD(1) AAS
別のところで質問したのですが、初心者歓迎スレのほうがいいと思いこちらで質問し直します。

Macのclang++でコンパイルしています。
cstdlibをインクルードしなくてもrand()が使えてしまうのですが、これはなぜでしょうか?
725
(1): 2021/07/06(火)01:49 ID:w3zU8vH7(1) AAS
>>724
手元のM1のでやったら普通にエラーになるけど?
printf("%d",rand());
だけ書いたやつ。

clangでもデフォはエラーだったような。C言語の方はコンパイルオプションで通せる。暗黙の関数宣言。

すまん、役に立てなくて。
726
(1): はちみつ餃子 ◆8X2XSCHEME 2021/07/06(火)05:58 ID:kwaneL8R(1/2) AAS
>>724
ヘッダファイルが他のヘッダファイルを内部で include している場合は有りうる。
たとえば iostream を include したら自動的に ios や istream なども include されることは保証された動作。
ただ、 cstdlib を (間接的に) include すると仕様で明言している標準ヘッダはないと思うので
rand がどこかで勝手に宣言されているのだとしたら処理系の固有の動作だと思う。

-M オプションで (間接的に include されているものも含めて) 依存関係があるヘッダファイルを
抽出できるからそれで確認できるよ。
727
(1): 724 2021/07/06(火)08:23 ID:9fUGxcs8(1) AAS
>>725
ありがとうございます。M1のclangではエラーが返るのですか…。コンパイラのバージョンの問題ですかね?
>>726
ありがとうございます。-M試してみました。
インクルードはiostreamだけにしていたのですが、ぞろぞろヘッダーファイル出てきまして、その中にcstdlibもstdlib.hもありました。
iostreamのインクルードを外すと当たり前でしょうが、それらのヘッダーファイルは表示されなくなりました。
つまり、iostream以下のヘッダファイルの依存関係にcstdlibがいたということですよね?
これは処理系依存なのでしょうか?
728
(1): はちみつ餃子 ◆8X2XSCHEME 2021/07/06(火)08:56 ID:kwaneL8R(2/2) AAS
>>727
処理系依存だと思う。
iostream が暗黙に include すると仕様に明記しているのは
ios, streambuf, istream, ostream の 4 つ。
外部リンク:timsong-cpp.github.io

あえていうなら cstdio の機能と結び付けるのが役割であるようにほのめかされている
ので普通の実装なら cstdio も include することになると考えてもいいと思うけど、
それ以上のことについてはっきりしたことは書かれてない。

rand が必要なら (たとえ実態として間接的に cstdlib が include されていても)
プログラマは明示的に cstdlib を include するほうがいい。
省1
729: 724 2021/07/07(水)08:49 ID:O+5oUfAp(1) AAS
>>728
なるほど、そもそも論まで含めてよくわかりました!
ありがとうございました!
730
(3): 2021/07/09(金)19:37 ID:We+HIKc2(1) AAS
C言語にpthreadを使ってマルチスレッドにするときの初歩的な質問をしたいのですが、
大域変数を複数のスレッドが読み書きする部分はミューテックスでロックしないとマズい、という
説明はわかった気がします。
では読むだけの部分はどうでしょうか。単にスレッドが変数の値を読みに行った瞬間の値を
知りたいだけならば、別にロックはしなくても害はないような気もしますが.... プログラム内の
別の箇所で書き込む部分はロックして、おかしなことが起こらないようにするとして。
それとも読むだけの場合もロック(書き込む場合に使うじミューテックスでロック)は必要でしょうか。
731: 2021/07/09(金)19:46 ID:TIX9j1Dy(1) AAS
必要ないぞ
732: 2021/07/09(金)21:27 ID:wrMb4YqN(1) AAS
必要だぞ
733
(2): 2021/07/09(金)21:31 ID:RRTM5Oms(1) AAS
>>730
スレッド実行中に書き換わる可能性があるなら必要。
変数を読むといってもCPUは一度内部のレジスタに読み込まないと処理できないので、
スレッド1でレジスタに読み込む→スレッド2で変数を書き換える→スレッド1に結果が反映されない
という事態が発生する可能性がある。
734
(1): 2021/07/09(金)22:32 ID:eGF9BJZ0(1) AAS
>>733
それ反映する必要ないだろ
単にスレッド1が先に読んだだけだし
それより読み書きがアトミックでないなら読み出し時にも排他しないと書き換え中の変な値を読んじゃうかと
735: 2021/07/10(土)01:06 ID:iVyIfxP9(1) AAS
書き換え後に古い値を取得してもええの?
736: 2021/07/10(土)04:35 ID:jD2ZKaD3(1) AAS
ええ場合もある
「単にスレッドが変数の値を読みに行った瞬間の値を知りたいだけ」はそれでええ場合のように聞こえるな
737: 2021/07/10(土)05:28 ID:TJHT9gxK(1/2) AAS
ええ場合も何も読んだ後で書き換えられたのをどうやって反映させるつもりなんだよ…
738: 2021/07/10(土)05:33 ID:Tru2G6zE(1) AAS
関連する操作すべてを優先順付きキュー経由にし
巻き戻し必要な操作にはジャーナル機能も入れ
やり直し再キューすんのよ
739
(1): 2021/07/10(土)05:36 ID:N1Z7WBqy(1) AAS
別スレッドからflgをいじって停止できるように

while (flg) {...}

と書いても、{...}の内部でflgをいじってないなら、
最適化で単なる無限ループに書き換えられて、flg変えても止まらない、
みたいな話なかったっけ。
740: 2021/07/10(土)06:47 ID:TJHT9gxK(2/2) AAS
>>739
それはまた違う話
volatile c言語 とかでぐぐれ
741
(1): 2021/07/10(土)07:11 ID:JKFXuD7+(1) AAS
スレッドAが 16bit長の整数を書き換える
スレッドBが 同じ16bit長の整数を読み込もうとしたとき
8bit長でしかアトミックな操作が保証されてないシステムだと

初期状態 0x0000 で スレッドA が 0xFFFF と書き換える

 A書き込み 上位FF
  (スイッチ)
B読み込み 上位FF
B読み込み 下位00
  (スイッチ)
 A書き込み 下位FF
省1
742
(2): 2021/07/10(土)08:27 ID:N9R+gZBb(1/2) AAS
>>734
いや、先に読んだだけっていっても、例えば
i f (v==1)
みたいな条件式を評価した段階では1だったけど、その先で急に2に変わった、とかだったらまずいだろw
743: 2021/07/10(土)08:34 ID:EesV0O7a(1) AAS
質問者の文言が

>単にスレッドが変数の値を読みに行った瞬間の値を知りたいだけ

>読みに行った瞬間の値を知りたいだけ

なので必要なし
以上
744
(1): 2021/07/10(土)08:39 ID:fOJ6OsHP(1/2) AAS
>>742
何もまずくないだろ…
745
(2): 2021/07/10(土)08:48 ID:N9R+gZBb(2/2) AAS
>>744
ifの中ではもう一度vの値を読んだときには2になってたりするわけよ
vが1の前提で書いたコードの中に2を突っ込んだらまずいよ
746: 2021/07/10(土)09:11 ID:16vz6VAu(1) AAS
>もう一度vの値を読んだとき

まずいのはこっちであって>>742のifや>>733自体は問題ないんでは。
747: 2021/07/10(土)09:15 ID:nctQkkF+(1) AAS
質問者が言ってないことに加えて勝手に仮定を追加してまずいとか言ってる>>745はもう黙ってほしい
748: 2021/07/10(土)09:51 ID:6bm+w6Lu(1) AAS
まずいのは>>745の頭だったというオチw
749
(4): はちみつ餃子 ◆8X2XSCHEME 2021/07/10(土)09:56 ID:11oc3t46(1) AAS
>>730
結論から言うとロックは必要。
同一のメモリに対するアクセスの少なくとも一方が書き込みである場合には衝突すると定義されている。
外部リンク:timsong-cpp.github.io
その場合にはデータ競合が発生する。
外部リンク:timsong-cpp.github.io

同時に起こりうるアクセスの内でひとつでも書き込みが存在したらそれはデータ競合の可能性があるってこと。

ミューテックスはミューテックスの所有権を取り合うことで競合を阻止する仕組み。
ロックというのは「ミューテックスをロックする (ロックしている間は自分がミューテックスの所有権を持っている)」
ということであって、対象となるデータそのもののアクセスを直接的に制御してるわけじゃないので、
省1
750: 2021/07/10(土)10:17 ID:fOJ6OsHP(2/2) AAS
>>749
at least one of which is not atomic
の意味ぐらいは理解してからレスしなよ
751: 2021/07/12(月)08:43 ID:Y3qBMERg(1) AAS
>>749
質問者は衝突しても問題ないケースで排他は必要かどうかを聞きたいんだろ
752: 2021/07/12(月)12:14 ID:uJpO0uZ2(1) AAS
「衝突しても問題ない」&atomicも使わない=「データ競合となっても問題ない」=「動作が未定義でも問題ない」なら
確かにロックは不要だけど。
753
(1): 730 2021/07/12(月)15:19 ID:VxiBn2TN(1) AAS
730です、どうもお騒がさせしております。
どうやら読み出しだけのときも基本的にはミューテックスを使うべきのようですね。

私の場合は域変数をカウンタとして使っていてその値をログ出力する、というような状況で、
なんとなくミューテックなしでもいいかと思ったのですが、ミューテックスを使わない場合は
気持ち悪い値がプリントされている感じですかね。
一般的な状況では、ミューテックスを使わなくても実害がないかを考えるよりはちゃんと
ミューテックスを使った方がよさそうですね...
1-
あと 249 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.068s