C++相談室 part150

■ このスレッドは過去ログ倉庫に格納されています
2020/03/24(火) 00:04:33.93ID:YFRNwZnv
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part149
https://mevius.5ch.net/test/read.cgi/tech/1581974381/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1556142878/


■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)

テンプレここまで
2020/05/01(金) 13:22:02.62ID:DtDCGOpK
SIMDなら32bit CPUとか64bit CPUとか関係ないし
2020/05/01(金) 14:33:57.85ID:RpLrbaMs
例えばRGBAの計算は早くなるよ
2020/05/01(金) 14:54:56.02ID:8qmJgOle
tclインタプリタに投げる
邪魔くさい
556デフォルトの名無しさん
垢版 |
2020/05/01(金) 15:22:00.38ID:tdkjZBPc
>>552
ベンチとるとおよそ4倍になりますよ。
2020/05/01(金) 16:04:33.87ID:uatxyJey
>>556
そのベンチどっかに貼ってみて
wandboxとか
2020/05/01(金) 16:07:40.19ID:wrmDV0oq
64bitを使っても、大部分のソフトウェアは速くも良くもならない事が知られている。
16bitから32bitの時には急激に多くのメモリが使えるようになって劇的にソフトウェア
が作り易くなったのと対照的。
メモリ容量に関してはたいていのアプリでは32bitでも既に十分。
速度に関してはそもそもCPUが扱えるデータビット数を多くしても滅多に速くならない。
速くなるのはグラフィックで単純なBitBLTを行うような場合のみ。
縮尺や回転が入るだけで64BITの効果は通常、生かせなくなる。
2020/05/01(金) 16:13:27.06ID:DtDCGOpK
>>554
変わった文字列処理だな
2020/05/01(金) 16:15:49.44ID:wrmDV0oq
>>554
RGBA計算も、(SIMDを使わずに)単純にデータバスが64BITになっただけでは速く出来ない。
なぜなら、R,G,B,Aはそれぞれ1バイトだから1バイトずつの計算するしかないため。
SIMDを使う場合は、CPUの種類によっては、SIMD自体のベクトルの要素数が倍になるため、高速化できる可能性はある。
ただしそれは、整数命令が64BIT化されたこととは直接関係ない。
SIMD命令のベクトルの「次元」が上がったかどうかの問題。
2020/05/01(金) 16:18:51.22ID:DtDCGOpK
>>560
なんでわざわざ関係ないことを書いてわざわざ混乱させようとするかなあ
562デフォルトの名無しさん
垢版 |
2020/05/01(金) 16:20:54.72ID:tdkjZBPc
64ビットの演算1回の時間で、32ビットの演算4回出来るんですよ。
2020/05/01(金) 16:22:03.22ID:wrmDV0oq
>>547
なりません。
ならないからこそ、GPGPUのようにマルチコア化が進められています。
SIMD命令も扱いにくいので、マルチコア化が適しています。
例えば、3Dのレイトレーシングなどは、SIMD化することはとても難しい
のですが、マルチコア化は比較的容易です。
人工知能のニューラルネットワークの計算はSIMD化し易い部分もあります。
しかし、300コアなどのマルチコアと、8要素のSIMD命令では、
前者に軍配が上がり易く、しかも、コア数が増えてもプログラムの修正が
ほぼ不要なので、マルチコアの方がSIMDより好まれます。
ただし、命令自体の速度がx86系は速いため、どちらが実際に速いかは
単純ではありませんが。
2020/05/01(金) 16:23:18.73ID:wrmDV0oq
>>562
CPUの一般論としてそんな事実は有りません。
あるなら具体的に書きましょう。
565デフォルトの名無しさん
垢版 |
2020/05/01(金) 16:25:25.15ID:tdkjZBPc
測ると大抵そうなってるというお話です。
2020/05/01(金) 16:33:18.55ID:DtDCGOpK
測定結果みせて
567デフォルトの名無しさん
垢版 |
2020/05/01(金) 16:33:57.33ID:tdkjZBPc
これ最初に気が付いたのは、固定小数点は速いらしいというのを見て、いろいろやってみたら、特に早いことは無くて。
じゃあ何が影響するかというと、単にビット幅だったんですよ。
floatとint32_tは同じ、doubleとint64_tは同じ。
つまり、アキュムレータの性能はあまり関係なくて、バス幅とキャッシュがすべてなんですよ。
じゃあ32ビット2回分が64ビット相当になるかというとそうでもなくて。
たいてい4回分で64ビット相当になるんですね。
2020/05/01(金) 16:37:43.83ID:DtDCGOpK
だから測定結果早くみせて
2020/05/01(金) 16:38:04.32ID:w4TGDP35
>>558
まさか!
2^32 bit 空間が狭すぎる、というのは windows XP の頃から問題になっており、2^64 bit 空間は必然でした

>メモリ容量に関してはたいていのアプリでは32bitでも既に十分。
個々のアプリ単体ではそうであっても、個々のアプリを複数稼動させる OS では32bit では足りないのでは?
そして 64bit OS に対応した 64bit アプリの存在も必要でしょう
570デフォルトの名無しさん
垢版 |
2020/05/01(金) 16:38:26.67ID:tdkjZBPc
自分で測ってもらえませんかね。
571デフォルトの名無しさん
垢版 |
2020/05/01(金) 16:41:04.33ID:tdkjZBPc
あと、僕はベンチマークのカタログとしてVSのテストエクスプローラ使ってますよ。
テストケースを一つずつ呼び出せるので大変便利です。
2020/05/01(金) 16:42:32.75ID:8qmJgOle
何をして速くなったと言っているのか不明なのに自分でってw
2020/05/01(金) 16:45:05.04ID:uatxyJey
>>570
測るのは自分でやるからベンチのソース見せてよ
比較実験やるにあたって環境も実装も変えたら比較にならないんだしさ
ここで逃げたらかなりださいと思うよ
574デフォルトの名無しさん
垢版 |
2020/05/01(金) 16:46:27.92ID:tdkjZBPc
>>573
そっちが出してくださいよ。
アセンブラ見ると速度がわかる奴。
2020/05/01(金) 16:51:31.85ID:wrmDV0oq
Qz は馬鹿だ。
2020/05/01(金) 16:54:18.57ID:uatxyJey
>>574
やっぱり無理か
そうだと思ってたよ
577デフォルトの名無しさん
垢版 |
2020/05/01(金) 16:57:02.32ID:tdkjZBPc
めんどくさいんですよ。
アセンブラ見れば速度がわかると言ってる時点で、僕は得るもの無いじゃないですか。
何か作業を手伝ってくれるならわかりやすく提示しても良いんですが。
作業を手伝ってもらうのに、色々教えないといけないなら、やっぱりめんどくさい。
2020/05/01(金) 17:00:18.65ID:DtDCGOpK
64bit命令を使うと4倍以上速くなるのは
64bitの乗算くらい

64bit加減算もCPUによっては数倍にはなる

それ以外は特殊な場合のみ
2020/05/01(金) 17:17:48.30ID:9YfMO5iP
intとint64_tで適当なfor分で配列計算やらせてみればわかる。
手元じゃint64_tのが若干遅い
2020/05/01(金) 18:21:10.38ID:wrmDV0oq
>>569
それは当たり前で、マシンには4GB以上のメモリが乗っているので、32BIT
では、OSレベルでは扱いにくい。
多くのプログラマにとって大事なのは、個々のアプリの問題だから、
OSレベルの話は関係ない。、
また、Windows OSがメモリーを食いすぎているという問題もある。
2020/05/01(金) 18:23:48.97ID:wrmDV0oq
>>580
補足すれば、グラフィック用のRAMは大きくなりがちで、最近のWindowsでは、
1つのWindowに仮想VRAMを割り当てているから、アプリが起動するたびに
グラフィック用になかなか大きなメモリーを消費する。
それと、ブラウザで複数のタブを開いている影響。
あれもグラフィックのレンダリング用に大量のメモリーを食っているのかもしれない。
2020/05/01(金) 18:31:06.76ID:IyliQkiG
>>577
他人を説得するつもりがないなら不特定多数が集まる場で自論を展開せず、馬鹿なこと言ってるなフフッて一人悦に入ってればいいんでない?
2020/05/01(金) 18:32:39.35ID:IyliQkiG
>>575
全面的に同意
2020/05/01(金) 18:40:33.09ID:DtDCGOpK
>>575
私も同意
2020/05/01(金) 19:15:32.79ID:wrmDV0oq
>>580
今は、見えないものまで含めれば50個のプロセスが動いているなんてことは当たり前になっている。
だから、個々のプロセスが80MBのメモリしか使って無くても、合計すれば4GBになる。
さらにファイルバッファや、OSが高速化のためにさまざまなキャッシュ的なデータを保持している。
しかも、ファイルバッファやキャッシュはいくらあっても不足する時代となった。
ブラウザがページを記録するためのキャッシュも必要だ。
そういう訳で、アプリが80MBしか使って無くても、OS全体では4GBではメモリが不足する。
というわけで、4GBを超えるメモリが必要となっている。
タスクマネージャーで見ていても、個々のアプリは、多くても数百MB程度のものが多い。
ファイル高速検索ツールなんかが、1.6GBも使っていたりするが、それは特殊。
だから「特殊なものを除いては」今のアプリが2GBを超えるメモリーを必要とすることは稀、だと言っている。
2020/05/01(金) 19:19:38.83ID:DtDCGOpK
それ
64bitで4倍
とどういう関係?
2020/05/01(金) 19:22:30.31ID:DtDCGOpK
32bit Windowsが4GBまでなのはWindowsの仕様であってCPU自体はそんな縛りは無いし
2020/05/01(金) 19:51:53.68ID:wrmDV0oq
>>587
典型的には、32BIT mode でも、PAE サポートによって OS は 4GB を超える
メモリーを扱えるね。
2020/05/01(金) 20:58:17.99ID:9yUywlA0
64GBまで使えるようになったのPentium Proからだぜ?w
Klamathより前!!
2020/05/02(土) 00:04:20.13ID:jVHOaTi/
>>547
釣り針でかいなw ここム板だぜw
2020/05/02(土) 00:05:14.57ID:jVHOaTi/
>>587
おまえ嘘ばかりだなw
2020/05/02(土) 01:38:26.25ID:2lkgjmOV
>>591
いや、彼は正しいことを言っている。
あなたがIntel CPUの仕様を詳しく知らないだけ。
PAEという仕組みなどで32BITモードでも4GBを超える物理メモリーを扱うことができるようになっていた。
593デフォルトの名無しさん
垢版 |
2020/05/02(土) 01:45:40.91ID:ZXOrLboX
PAEが何なのか全く分かってなさそう
2020/05/02(土) 02:28:22.28ID:2lkgjmOV
QZは女なのだろうか。
ショックかも知れないがはっきり言えば、本質的に物事が正確に理解できていないようだ。
2020/05/03(日) 09:20:54.04ID:slLa0KBW
EMSなら前に聞いたことがある
2020/05/03(日) 09:24:35.32ID:WVD/IFzz
8bit CPUは256Bしか扱えないと思ってる人いる?
2020/05/03(日) 09:29:47.71ID:6v/wuiGx
16bitのCPUでも16bitアドレスの最大値である64KBを超えて1MBもアクセスできていたからな。
2020/05/03(日) 10:03:25.11ID:WVD/IFzz
>>594
女なら180度対応を変えます
2020/05/03(日) 10:22:47.73ID:LxtsyLet
>>597
16BIT CPU であった 8086は、16bit アドレスを超える範囲は、セグメントレジスタ
と合わせた seg:ofs の形式の far pointer を使わなくてはならならず、
単純に扱えるのは16BITまでで、16BITを超えた範囲では、seg レジスタの値を
足していかないといけなかった。しかも、segがアドレスの上位16BITだったなら
まだしも、16バイト単位のアドレスだったので、segレジスタに入れる値を計算
するのがとても重くなってしまっていた。
ところが、Z80 などの 8BIT CPUは、普通に 16BIT レジスタの
HL や DE, BC, IX, IY をもっており、8086 と比べれば扱いは容易だった。
その意味では、8086は、メモリーアクセスに関してはZ80と同じくらいしか
能力を持っていなかった。
それで8086の16BITモードでは限界が来て32BITモードのOSが待望された。
そしてMacのGUIを真似た機能を持っていたこととも合わせて32BITモードで
動いたWin95となった。

ただし、このような状況は64BIT化に関しては全く無い。
2020/05/03(日) 10:32:19.81ID:6v/wuiGx
そりゃまあ、64bitCPUがすでにいきわたっていてOS変えるだけで対応できたからね
WINAPIだって16→32のコンパイルはまず動かないけど32→64なら普通は動く
DOS時代のUMBみたいなみみっちい事態にならなくてよかったじゃん
2020/05/03(日) 10:35:22.17ID:OJMdC3Cv
86用コンパイラでnearとfarの他にhugeが有ると知らず、無限ループ作ってOSごと来なくなったあの頃
2020/05/03(日) 11:16:28.83ID:WVD/IFzz
結局64bit CPUだと速度4倍のコードは?
2020/05/03(日) 13:08:16.85ID:m/iHOjCC
long longとint64_tの違いってlong longは環境によって64bitじゃなくなるけどint64_tは常に64ってことですか?
2020/05/03(日) 13:13:36.85ID:LxtsyLet
>>603
まあ、そういうこと。
2020/05/03(日) 14:04:07.52ID:slLa0KBW
           |
            |  彡⌒ミ
           \ (´・ω・`) またhugeの話してる・・・
             (|   |)::::
              (γ /:::::::
               し \:::
                  \
2020/05/03(日) 14:24:10.29ID:m/iHOjCC
>>604
ありがとうございます
2020/05/03(日) 15:56:11.79ID:gvP0MmQx
32bitの環境で32bitの境界を超えるような64bit値の計算ってどうやって実現してるの?
2020/05/03(日) 16:00:56.90ID:uzK0zokK
cpuに命令なければソフト的にやるに決まってんじゃん
2020/05/03(日) 16:06:34.35ID:uzK0zokK
ちなみに32bitの掛け算の答えに64bit必要ってわかってない人多いよね
同様に64bitなら128bit
610843
垢版 |
2020/05/03(日) 16:22:11.00ID:OGvyQUVV
>>607
まずは筆算の足し算からやり直そうか
2020/05/03(日) 16:54:49.03ID:+PpSUNNp
64bitだとdoubleとかの書き込みはアトミックになるの
612デフォルトの名無しさん
垢版 |
2020/05/03(日) 17:17:29.21ID:VkK7EFZv
C/C++にキャリーフラグ観る機能が無いのはなせ?
2020/05/03(日) 17:56:41.69ID:baOIQvWk
アトミックにしたけりゃstd::atomicを使え
使わない場合は保証されない
2020/05/03(日) 18:16:14.79ID:uzK0zokK
>>612
いれるとしたらどんな仕様でいれる?
そこまで考えてから書いてみたんだよな?
2020/05/03(日) 18:19:51.49ID:uzK0zokK
>>613
64bitでない環境だとatomic持ち出したところで使えないじゃん
2020/05/03(日) 18:25:40.26ID:baOIQvWk
使えるぞ
内部でロックするから遅いけど
2020/05/03(日) 20:09:19.86ID:7Ft0FuY4
>>598
90度だろ?
2020/05/03(日) 20:16:01.21ID:s7MuzCvB
モダンc++入門ってどこみたらいい?
2020/05/03(日) 21:01:49.43ID:0Fr9Yznx
cpprefjp
2020/05/03(日) 22:43:31.73ID:WVD/IFzz
>>611
ほとんどの環境でYES
32bit CPUでもアトミックな環境もある
2020/05/03(日) 22:46:00.66ID:WVD/IFzz
>>612
キャリーフラグが無いCPUも有るから
CPU固有の機能はintrinsicを使う
2020/05/03(日) 22:52:17.09ID:WVD/IFzz
>>609
整数の乗算を全範囲正確に求めたい場合の話だな
これもC++では書けない
intrinsicを使う
2020/05/03(日) 22:53:53.78ID:WVD/IFzz
>>617
なんで90度?
180度だって書いてるのに
2020/05/04(月) 03:33:26.41ID:BnrivxPo
int128でもint256でも自由に型が作れるのがC++の強みなのに書けないってw
2020/05/04(月) 06:12:26.01ID:/zUHO7E0
int_<256>みたいの作ってたけど
サイズが発散する問題がすぐ起きる
626843
垢版 |
2020/05/04(月) 07:19:32.37ID:oxprEh+7
>>620
> 32bit CPUでもアトミックな環境もある
具体的な環境名教えて
627843
垢版 |
2020/05/04(月) 07:20:47.92ID:MJc5y26W
>>623
(女は)話をはぐらかすって事だろ
2020/05/04(月) 07:22:03.70ID:nMCshN11
x86
2020/05/04(月) 08:03:18.75ID:S2aUUuq2
shared_ptr<Hoge>をvoid *の領域に格納したいのですがどうすればいいでしょうか?
SetPointer(void *),void* GetPointer()で設定します
shared_ptr<Hoge> hoge
として
SetPointer(hoge)

取り出す時
shared_ptr<Hoge> hoge = GetPointer()
2020/05/04(月) 08:04:47.44ID:S2aUUuq2
後、SetPointerする前にshared_ptrの参照カウントを一つ増やしたいです。
2020/05/04(月) 09:54:06.17ID:Fiop0J3e
>>629-630
所有権込みで格納したいだけなら。
SetPointer(new shared_ptr<Hoge>(hoge));
shared_ptr<Hoge> hoge = *static_cast<shared_ptr<Hoge>*>(GetPointer());
あとはどうにか delete が抜けないようにする。
2020/05/04(月) 10:27:13.66ID:aMJtnkBw
本当にshared_ptrごと格納する必要があるの?
これで良かったりはしない?

shared_ptr<Hoge> p(new(buffer) Hoge, [](Hoge* p){p->~Hoge();});
2020/05/04(月) 11:04:11.62ID:BnrivxPo
つまりshareする気がないけどshared_ptrを使いたいわけだな
2020/05/04(月) 11:24:26.33ID:7IQ5DE83
誰かと食べる気はないけど、マックのシェアポテトを食べたい感覚だね
2020/05/04(月) 12:42:16.41ID:S2aUUuq2
>>632
これ難しすぎて解読できません

まず、やりたいことはWindowsのTreeViewでノードを追加するときに、ノードにLPARAM型の任意のデータを関連づけれるんですが、そこに他の関数から受け取ったshared_ptr<Hoge>を関連付けたいのです

shared_ptrごと格納する必要ないと言えばないのかもしれません
でも中身だけ格納すると、deleter?の情報がとんじゃう?
2020/05/04(月) 12:55:51.13ID:S2aUUuq2
>>631
こっちの方で後で試してみます
2020/05/04(月) 13:16:44.39ID:0skWT8b9
なにがしたいのだかいまいちよくわからない
2020/05/04(月) 13:20:23.37ID:/R09lZ8N
所有したいのか/参照持ちたいだけなのか
shared_ptrとして使う必要があるのか
参照だけ持ちたいとしてダングリングの可能性が有るのか
2020/05/04(月) 13:46:24.04ID:S2aUUuq2
あーあ。shared_ptrごと格納できるならそっちの方がいいです。
そうしないと誰が最後にdeleteするかめんどくさくなりなすね。
すみませんでした
2020/05/04(月) 13:47:34.57ID:aMJtnkBw
TreeViewが持つのはポインタだけで、オブジェクトの寿命管理するわけじゃないんだろ?
だったらshared_ptrのdeleterの情報なんか渡す必要ないんじゃないか
オブジェクトの寿命管理する奴が知ってればそれでいい
2020/05/04(月) 13:56:33.16ID:tzWRkvZC
>>639
shared_ptrはlparamに収まらないから無理
sizeofで確かめてみ
2020/05/04(月) 14:01:15.39ID:S2aUUuq2
すみません。何か頭混乱してきた・・
>>630が余計だったのか・・

まず、基本方針としてオブジェクトの寿命管理を楽にするためにクラス間でデータをやり取りする場合は
全部shared_ptr経由で参照カウントにより自動で管理してもらおうという方針です。

ですが、既存のライブラリとの都合で例えば、今回のTreeViewのノードにはLPARAM型のデータしか関連づけらられない
ということで、ノードに関連づけるときに参照カウント手動で?増やしてあげて、ノードを削除するときに、
参照カウントを手動で減らして?あげて調整するものなのかなぁーと思った次第です。
2020/05/04(月) 14:02:14.17ID:/R09lZ8N
データの本体は別にあってそっちで所有権管理しているなら、treeviewにはshared_ptr::getで得られるpointer持たせればいい
使う側でshared_ptrである必要があるなら、shared_from_this使う

ダングリングする可能性無いならならこれでおk
2020/05/04(月) 14:12:18.91ID:aMJtnkBw
void*で渡しちゃう以上はTreeViewに参照カウント減らさせるのは不可能なので、そこは外側で管理してやるしかない
だったらTreeViewはshared_ptrがどうのこうのという情報は知らなくていいし、知らせるべきでない
2020/05/04(月) 14:19:40.83ID:tzWRkvZC
>>644
TreeViewってのはWindowsの既存のコンポーネントだろ
ちょっとまとはずれだよ
答えは >>631 で出てる

>>639
手動deleteが本当にいやならあとは黒魔術使うしかないね
unique_ptrなら64bitにおさまるだろう
2020/05/04(月) 14:23:16.16ID:aMJtnkBw
>>645
既存のコンポーネントだからだよ
shared_ptrのこと知らんやつにshared_ptr渡したってろくなことにならんだろ
2020/05/04(月) 14:33:47.37ID:tzWRkvZC
>>646
荒らしたくないがもうちょっと質問者の内容くみとってから返事書いてやれよ
shared_ptrの型で渡すんじゃなくてvoid*の型で渡すって最初から言ってんじゃん
2020/05/04(月) 14:47:05.48ID:aMJtnkBw
何が気に食わなくて噛み付いてるのかよくわかんないけど
TreeViewはshared_ptrのことなんか知らないんだから、そんなものは知らせずに
関連のあるデータを与える(要はshared_ptr<Hoge>*じゃなくてHoge*を渡す)方が設計すっきりするんじゃない?
って言ってるだけなんだがそんなにおかしいか?
2020/05/04(月) 14:51:53.81ID:Zy37Y+hL
何か追加して問題が出て別の何か追加して解決するの繰り返し
C++の仕様は余計なものが多い
メモリーの所有権の移動とかの暗黙知の極みを気にできるくらいならdelete忘れることはないだろうに
2020/05/04(月) 14:57:19.53ID:Fiop0J3e
Hoge* 渡して済むなら最初から相談なんて発生しないだろうと思ってたんだけど、
>642 みたいな「基本方針」だと shared_ptr の必要性が胡散臭いんで、確かに
Hoge* で済む可能性もありそうな気がしてきた。
2020/05/04(月) 15:00:15.13ID:tzWRkvZC
>>648
shared_ptrでわたってくるものをvoid*で管理したいってことで
それは質問の前提条件
解としてHoge* にするってのは破綻するからダメでしょ
2020/05/04(月) 15:10:46.19ID:S2aUUuq2
>Hoge* 渡して済むなら最初から相談なんて発生しないだろう
そうです。Hoge*で渡したくないから質問した次第です。

元のデータが先に捨てられようと、先にTreeViewのノードが破棄されようと、どっちが先でも
OKなように、それらを意識しないようになるべく参照カウントの仕組みで破棄したかったわけです。
■ このスレッドは過去ログ倉庫に格納されています