C++相談室 part135
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい。 !extend:on:vvvvv:1000:512 C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。 前スレ C++相談室 part134 http://mevius.5ch.net/test/read.cgi/tech/1516406742/ このスレもよろしくね。 【初心者歓迎】C/C++室 Ver.102【環境依存OK】 http://mevius.5ch.net/test/read.cgi/tech/1509780815/ ■長いソースを貼るときはここへ。■ http://codepad.org/ https://ideone.com/ [C++ FAQ] https://isocpp.org/wiki/faq/ http://www.bohyoh.com/CandCPP/FAQ/ (日本語) VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
実行してるということはコンパイルは通ってるということだと思う つまりコンパイルの問題ではなく、コンパイルエラーではないだろうという推測 >>230 「実行すると」 ビルド時のコンパイラなどからのエラーではなく、 プログラムを実行したときの挙動についての質問のようですよ 初心者つってるから どこまでがコンパイルで どこからが実行なのかの 区別からあやしいと見ている 実行時エラーにしても stopダイアログなのか 結果がおかしいのか あの質問では言ってない コンパイルして(リンクを)実行すると だったりして しつけえな ここはプログラム技術板 技術的な内容が皆無のレスでひっ絡んでくるなカス >>224 何を実行するのか目的語をはっきりさせろ プロ意識が欠けている pthread を使ってループ処理をマルチスレッド化したのですが、シングルスレッドと同じスピードしか出ませんでした。 pthread でこういう事やっても無駄なんでしょうか? 流石に情報が少なすぎて このままだと下手糞としか言いようがない。 ソースコード貼り付けれ pthread使うとひとつの処理が倍速にでもなると思ったのだろうか 舌足らずですみません。コードはこんな感じです。 threadFunctionは単なる加算値、joinFunctionは集計処理です。 コアは物理2論理4です。 template< class ArgType > void Reduce( std::vector< ArgType >& threadArgs, void* (*threadFunction)(void*), void (*joinFunction)(std::vector< ArgType >&) ) { const size_t threadCount = threadArgs.size(); threads.resize( threadCount ); std::vector< void* > voidPtrArgs = CastArgsToVoidPtrs( threadArgs ); for ( int threadIndex = 0; threadIndex < threadCount; ++threadIndex ) { sched_param schedParam; schedParam.sched_priority = sched_get_priority_max( SCHED_FIFO ); pthread_attr_t threadAttribute; pthread_attr_init( & threadAttribute ); pthread_attr_setschedpolicy( & threadAttribute, schedPolicy ); pthread_attr_setinheritsched( & threadAttribute, PTHREAD_EXPLICIT_SCHED ); pthread_t& thread = threads[ threadIndex ]; pthread_setschedparam( thread, schedPolicy, & schedParam ); pthread_create( & thread, & threadAttribute, threadFunction, voidPtrArgs[ threadIndex ] ); } for ( int threadIndex = 0; threadIndex < threadCount; ++threadIndex ) { pthread_t thread = threads[ threadIndex ]; pthread_join( thread, NULL ); } joinFunction( threadArgs ); } >>243 この世界では、何かやって思い描いてたようにならなかった場合 まず自分の能力不足を疑うのが鉄則 >>248 アハハハハ!ジョークのつもりかなんか? そうじゃないならjoinの動きを勉強しろ いまだに関数ポインタ使ってるのか。野蛮人。 std::functionってスレッドセーフじゃないの? いまだ関数ポインタが使いこなせないんだけどやばいかな? 考えたらjoinの問題じゃないか もし「単なる加算処理」が1スレッドでメモリ帯域使い潰していたらマルチスレッドにしてもどうしようもないのは明らかだよ >>253 未だに関数ポインタなんて使ってるほうがやばい 画像処理で合成処理をパラメータでもらう場合があるんだが その場合内部処理と対応させるために関数ポインタは使うが そういうのもダメ? ダメってわけじゃないけどさあw C++ならもっと柔軟性のあるやりかたが幾らでもあるってこと std::byteが邪魔すぎるんですけどg++で無効にするオプションってありますかね? >>257 あんた昨日のおじいちゃんだろ。 functionの時代もとっくに終わってるぞ。 autoとlambdaで関数ポインタを使うべき。 >>258 ライブラリ制作者でもなければ関数ポインタなんぞ触らんよ。 よほどCとの兼ね合いが無いと。 >>248 threadcountいくつになってるの? 忘れがちなことだが std::function は実行時の型を扱う。 画像処理などのようにヘビーな繰返しがあるような場面では関数ポインタを使った場合との間に深刻な速度差が生じることもなくはない。 >>248 関数名からして、一度のreduce処理量は大したことなくて、何度も繰り返し呼んでない? thread処理に必要な処理量が相対的に無視できなくなってるんじゃね? スレッドは4本に制限して、各スレッドが処理する量を増やすかスレッドプール式にしては? C++だから関数ポインタ使わないとか頭おかしい 関数ポインタのほうが高速かつシンプルに書けるならそちらを選択すべき 富豪かどうかはおま環だろ だから自己申告しないヤツが悪い なんでこっちがエスパーみたいなことしなきゃいけないんだ わたくしは教えないがあなたがわたしの環境を忖度しろってか? ヴァカじゃねえの? アフォに対してちゃあんと「テメーのスペックはいかほどですか」と尋ねろクズ 富豪かどうかはわからない、それを言わない人間がまず間違い、 それを逆手にとって相手をマウンティングするアフォがいるから話が進まない どんなスペックだろうと他のソフトがどれだけメモリや処理時間を喰い潰していようと自分の処理はサクッと終わらせたいといつも思う >>260 へんてこりんなマウンティングするやつだなあ ちなみに昨日なんて俺書き込んでないからw >>248 調べてみたけどさっぱり判りません。 pthread_joinで各スレッドの終了を待って、その後、集計処理をするというのはごく渡り前の処理に見えるのですが、 何が行けないのでしょうか? 別の方法でスレッドの終了を待たねばならないのでしょうか? 自分勝手デスミア線が、具体的に問題点、改善点を指摘して下さいm(_ _)m。 いいから「単なる加算処理」全部見せろよこの包茎野郎 threadFunctionが、 void* CalcBasicStatics( void* threadArg ) { BasicStaticsThreadArg* arg = reinterpret_cast< BasicStaticsThreadArg* >( threadArg ); double intervalOfX = arg->intervalOfX; double x = arg->dividedRangeOfX.start; double sumOfY = 0.0; double sampleCount = 0; const sc::Sampler& f = arg->f; while ( x <= arg->dividedRangeOfX.end ){ double y = f( x ); sumOfY += y; sampleCount++; x += intervalOfX; } arg->sumOfY = sumOfY; arg->sampleCount = sampleCount; return nullptr; } joinFunctionが、 void CalcBasicStaticsJoin( std::vector< BasicStaticsThreadArg >& args ) { double sampleCount = 0.0; double sumOfY = 0.0; for ( int i = 0; i < args.size(); ++I ) { sumOfY += args[ i ].sumOfY; sampleCount += args[ i ].sampleCount; } for ( int i = 0; i < args.size(); ++i ) { // 結果を書き込み BasicStaticsThreadArg& arg = args[ i ]; arg.average = sumOfY / sampleCount; } } です。細々すみません。 そのコード見ても 並列度もスレッドあたりのサンプル数も 1サンプルあたりのコスト(f)もわからないので まるで意味がない 2または4並列で、1スレッドあたり1〜10Mサンプルくらい処理するようにすれば 速くなるか少なくともスレッドを使わない場合より遅くならないと思う 同じ速度ということはメモリ帯域が律速なのかもね fでメモリのどっかから数値を読んでいるんだと思うけど、 これがなるべく連続したアクセス(局所化を謀る)になるようにループを構成できれば速くなるかもしれない。 この辺りはググれば色々参考になるページがあると思うが いまググッたらそれらしいページがあったので書いておく http://myoga.web.fc2.com/prog/cpp/opti02.htm 仕様として外からfが与えられるなら無理な話かもしれない。 もちろん interval が 1 で f(x) が { return v[x]; } のような最適なケースよりは速くならないので その辺りは無駄な努力をしないよう測っておきましょう。 fの中身が公開出来るなら公開して 複数あるならそのうちの1個でいいから あと、 1回のthreadFunctionで何個くらいfを計算する? >>250 joinについて勉強しろとか偉そうに言ってたのは何だったの >>278 こりゃ「多分」joinの問題じゃないなと判断して>>254 を書いたんだが これくらいのコンテキスト読めないとマルチスレッドは無理だよ fやら具体的なargsの内容やら処理時間測定のやりかたも記述されてないし んなもの誰も答えられるかよ >>279 違う違う なんで明らかに間違えてる事を偉そうに述べられるのかと聞いてんだけど 読解力もスキルもないのか >>281 本当に「明らかに」だと思ってるの?バカですか? サンプルレベルのJoinの使い方をみて 「アハハハハ!ジョークのつもりかなんか?そうじゃないならjoinの動きを勉強しろ」 は流石に笑ってしまう cin で、個数の決まっていない整数たちを読み込みたいのですが、どうすればいいでしょうか? 整数たちの個数 n が分かっていれば、以下のように読み込めばいいですが。。。 vector<int> v; int i; for (int i = 0; i < n; ++i) { cin >> i v.push_back(i) } >>282 明らかにだろどう見ても。 何をどう勘違いしたのか説明してくれよ。 >>285 他に入力がないなら cin.eof() で入力の終了を検出できるよ。 cin のブール演算を使ってもいいけど、どうにも慣れなくてね(個人の見解)。 >>287 ありがとうございました。 別の質問なのですが、一般的に、vectorの使用頻度というのはどれくらいでしょうか? 配列でやれることもすべて vector を使ってやるという人は多いでしょうか? それとも、効率などを考えて配列で極力済ませるという人が多いでしょうか? もちろん、ケースバイケースでしょうけれども、そのあたりの常識がないので、大体 どんな感じなのかが知りたいです。 自分としては、効率など細かいことは考えずに、vectorを使って問題ない 場面ではvectorを使うという風にしたいのですが。。。 vectorを使っても速度などの点で問題ない場合、一般的なプログラマーなら どうするのかが知りたいです。 vector<int> v; int n; cin >> n; int t; for (int i = 0; i < n; ++i) { cin >> t; v.push_back(t); } int *p; int n; cin >> n; p = new int[n]; for (int i = 0; i < n; ++i) { cin >> p[i]; } どちらにするのが普通なのかの常識がありません。 >>290 生のnew/deleteは、なるべく使わないのがいい。delete忘れ、例外などでバグの元や維持コストになる。 >>291 ありがとうございました。 ということはできるだけvectorを利用したほうがいいということでしょうか? >>292 動的にサイズが変わらないなら配列かstd::array。 動的にサイズが変わるならstd::vector。 >>290 上だったらv.reserve(n)しておこう >>289 私は書き始めは std::vector を専ら使っており、後で他のコンテナに換えています >>296 普通の人間なら、文脈を読み取れるけど、俺はコンピューターに近いんだ。 >>289 実用上の問題が無いことがわかっている範囲内であれば、 深く考えずに vector だけで乗り切るのも悪い選択じゃないと思うよ。 ただ、使い分けることで意図を表現しやすい。 たとえば list を使っていれば要素の挿入や削除が頻繁なデータなんだなって思うし、 array が使われていれば要素の個数が固定なんだなって思う。 速度的に影響がない程度の規模であっても、 それが適しているような操作をこれからするのだという意思表明は人間がプログラムを読むときのヒントになる。 そして、そういうヒントは書いている途中にこそ必要なものなので、 >>295 のように後から整理していくスタイルは個人的には好きじゃないな。 >>298 >それが適しているような操作をこれからするのだ うーむ、いろいろと考えさせられます std::vector でなら使えても、std::list では使えない、というのはあるから、最初からそれを考慮しておくのは…よくありますねえ vector は list に比べた場合、 データがメモリ上隣接して並んでいるので →そういう引数を要する各種 API にそのまま渡せる →メモリアクセスが局所的にできてキャッシュが効く 予約領域を拡張する場合にのみアロケータが呼ばれるので追加時のアロケータによるオーバーヘッドが低い とかの良い特性もあるので要素のコピーが軽くて個数が小さいものはvectorにして損することは少ない BidirectionalIteratorとRandomAccessIteratorだろ 規格用語で言えば短く済む std::listはメモリ局所性がないので今どきのマシンだとクソ遅い 積極的に使う理由は基本的にない メリットとデメリットを見極められないとコンテナを使いこなすのは難しい 昔から配列を弄り倒している古参にとってはこんなに便利な物はないと思うがね 90年初頭辺りにタイムスリップして実際に構造を真似てフルスクラッチでテンプレートなんぞなかった世界で組んでみればコンテナの挙動は自ずと理解できると思うが時代がわるかったな 今は何も苦労しなくても容易になんでも手に入る世界だからな 修業が足らんよ青二才 >>303 その使い所がよほど特殊な状況以外にないんだよ 大規模C++ソフトウェアデザインという本を読んでいます。 冗長インクルードガードが紹介されているのですが、効果あるんですかね。 古めの本なのですが、最近のコンパイラだと意味ないですかね #pragma once って規格化されたんだっけ? されてない しようしようと20年言われ続けて技術的な問題でできずにいる 243です。 アドバイスを頂き検討したのですが、メモリが散らかっているのが原因と判断しました。 都合により細々とした実装の話は割愛しますが、付き合ってくれた皆さんありがとうございました。 >>305 その特殊な状況の為にlistが存在する 私の場合は特殊なプログラムを書くことが多いので 使いどころは多いのかもしれない また、普通の組み込みC言語でも簡易な片方向リストとかを使ったりする (C++じゃないのでlistは無い) >>309 技術的な問題ってなに? 既に実装してる環境の方が多くね? >>313 プリプロセッサは C++ じゃないからね C++ 以外の言語と共有しているツールなので それらと歩調を合わせる必要があるし プリプロセッサだけ独立の規格にするなら C++ を含め、諸言語の規格も プリプロセッサのバージョンとどう付き合うのか 策定せにゃならん >>316 意味わからん C/C++の規格にプリプロセッサの仕様もあることを知らんのか? そもそも他の言語と共有してる環境なんて見たことないし 現行では、 #include ディレクティブは「対象ファイルの内容がそこに書かれているかのようにふるまう」という規則なので、 ヘッダファイル内のプラグマ (#pragma once) の解釈が始まるのはインクルードされた後になる。 もちろん対象範囲がコンパイル単位全体に及んでしまっては #pragma once の意味がないが、 現状の仕様に辻褄を合わせるとそうなる。 実装した処理系がもうあるんだから実装に沿うように規定しなおすってことはできなくは無いんだろうが、 #pragma once を仕様に入れるのに #pragma once の項目を追加すれば済むわけではないってことは理解してくれ。 それと、プリプロセッサの仕様は C/C++ の一部なのは確かだが、 挙動を規定しきれていないのじゃないかということは指摘されている。 https://qiita.com/ruiu/items/4d471216b71ab48d8b74#3%E6%9C%8817%E6%97%A5 うやむやでやってきてるところを整理する必要は有ると思う。 >>317 Haskell (GHC) は C プリプロセッサを使うよ。 汎用的に使いたいなら M4 とかの方がいいとは思うけど、 Cプリプロセッサに慣れている人は多いから……。 また別な話 #includeしようとしているファイルが 過去に#includeしたファイルと同一かどうか という判定も意外に厄介だね ハードリンクできるファイルシステムと そうでないファイルシステムがあったりするし ハッシュが一致しても衝突かどうかの問題もある ハードリンク、シンボリックリンクが無いファイルシステムだったとしても、サーチパスの問題も思いつくな。 たとえばカレントディレクトリと、カレントディレクトリ直下の foo ディレクトリからヘッダファイルを探すようになっているとき、 #include "bar.h" と #include "foo/bar.h" は同じファイルを指しているが、表現が異なる。 同一のファイルとして除去すべきだろうか? #if **** #pragma once #endif とかどうなるの? 複数回のインクルードで条件がちがっていたら? >>318 > 実装した処理系がもうあるんだから実装に沿うように規定しなおすってことはできなくは無いんだろうが、 規定すればいいだけだろ? どこに技術的な問題があるんだ? 政治的な問題だと言うならまだしも >>319-320 みたいな話は処理系定義ですむ話 >>321 は少し悩ましいがそもそも途中まで読んでから#pragma onceとか言われても面倒だから書くならファイルの最初に書けとかの制限をつければいい > 挙動を規定しきれていないのじゃないかということは指摘されている。 いやいや、その子ちゃんと規格読めてないだけでしょ w > Haskell (GHC) は C プリプロセッサを使うよ。 仕様を流用してるだけでしょ? 何かのコンパイラと共有してるわけじゃないと思うが 君よりよっぽど賢い人達が20年間悩み続けて未だに出来てないことを舐めない方がいい >>323 別に悩み続けてなんていないでしょ w #pragma onceで事足りてるからわざわざ政治的なことに足突っ込みたくないだけ 新規格の季節になると毎回のように標準化委員会の議題に上がってるんだが? モジュール方式になったらヘッダファイルが要らなくなる? >>322 > 処理系定義ですむ話 それはおかしいでしょ ハードリンクできる処理系からできない処理系に移植したtarボールの #includeの挙動が未規定なら結局インクルードガードを自前で書くことになる >>325 でも誰も進めようとしないんだろ w よくある話 >>327 C/C++ ってそういう言語だしそもそも環境変える予定があるならそんなものに依存したファイル構成にしないでしょ #pragma once なんて once upon a time だぜ 今はもうだれも気に留めてやしねぇ ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる