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 >>208
何言ってんだおまえ
頭悪すぎるにもほどがあるだろ COWなstringは効率が悪くてマルチスレッドとの相性が最悪なのでとっくの昔に打ち捨てられました
規格のCOW実装許容するための記述はC++11でバッサリ捨てられました
今はCOWは規格違反です 値渡しや戻り値で戻せることと、
std::string内部での(ヒープ)メモリ管理の詳細は関係なくね??
引数や戻り値としてスタックに構造体を積めるようになった時点で値渡しや戻り値で戻せることとはほぼ自明
(よほど変なコピコンを定義してコピーをわざと不首尾に終わらせない限りそれはできる >>213
まあそうだけれど無駄なコピーはなるべく避けましょうということで 今時のコンパイラは、そこらの人間よりよっぽど高度な最適化をするから、素直で単純なコードを書くと速くなる。
効率化するつもりで余計なことをすると、コンパイラの最適化を妨げて、かえって効率が落ちたりする。
本当に重要な部分は実測しながら試行錯誤、それ以外はできるだけ素直なコードを書く、ってあたりが基本。 stringを値渡しせずにconst参照等々で渡すことはc++の基本なので、素直で単純なコードの部類に入ると思うが。 先生!OpenMPへの展開も自動でやってくれるんですか? 値渡しを素直なコードとか言う人って他人の書いたコード読まないんだろうな
宿題以外で何か書いたことあるのか const参照渡しが基本だったのって C++11 以前の世界の話だよね…
幸い、近頃はそんなコードをあまり読まずに済んでるけど。
余計なことをしない、ってのが大事なんだよ。
参照でなきゃいけない理由がなければ、参照を使うべきじゃないんだ。 初心者です。
今書いてるプログラムをコンパイルして実行すると、エラーが出たり出なかったり謎の挙動を起こします
最初はエラーが出て、その後数回、コードを一切変えずコンパイルしなおして実行すると急にエラーが出ず上手く行ったりします。
これって何が原因なのでしょうか…
こういう事ってよくあるのですか? >>224
そのエラーとやら、もしかして警告か?
エラーは直すまで何度コンパイルしても絶対に通らない
警告はコンパイルが完了しオブジェクトファイルができる
そのコンパイルとやら、もしかしてビルドか? それともmakeか?
ビルドやmakeはオブジェクトファイルとソースファイルの日付を比較して
ソースファイルのほうが古いとコンパイルを省く
だから警告が出てからもう一度ビルドしても同じ警告は出ない
おそらく、こういうことだと見受ける >>227
日本語読めないのかよ...
> 実行すると、エラーが出たり出なかったり謎の挙動を起こします 実行してるということはコンパイルは通ってるということだと思う
つまりコンパイルの問題ではなく、コンパイルエラーではないだろうという推測 >>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年言われ続けて技術的な問題でできずにいる ■ このスレッドは過去ログ倉庫に格納されています