C、C++の最適化について語るスレ

このエントリーをはてなブックマークに追加
411r
一番早いminはどれ?
typedef int int32_t;
int32_t min0( int32_t a, int32_t b ) {
    return a < b ? a : b;
}
int32_t min1( int32_t a, int32_t b ) {
    return ( ( a < b ) * a ) | ( ( b <= a ) * b );
}
int32_t min2( int32_t a, int32_t b ) {
    // mathmatic shift
    return ( ( ( a - b ) >> 31 ) & a ) | ( ( ( b - a - 1 ) >> 31 ) & b );
}
int32_t min3( int32_t a, int32_t b ) {
    // logical shift
    return ( ( ( a - b ) >> 31 ) * a ) | ( ( ( b - a - 1 ) >> 31 ) * b );
}
int32_t min4( int32_t a, int32_t b ) {
    return ( ( ( ( a - b ) >> 31 ) & 0x01 ) * a ) | ( ( ( ( b - a - 1 ) >> 31 ) & 0x01 ) * b );
}
412デフォルトの名無しさん:2006/01/05(木) 23:54:38
乗算が含まれている時点で俺としては1, 3, 4を却下する。
413デフォルトの名無しさん:2006/01/06(金) 00:02:59
>>411
俺も一時期、この手のヤツいろいろ試してみたけど十中八九 min0 が最速になるよ。
414r:2006/01/06(金) 00:13:00
>>413
そっか。一番短いもんなあ。
なんか三項演算子ってジャンプしそうだから、
ジャンプしなさそうなのがいいかなって思ったけど。

>>412
整数型でも、かけ算ってやっぱまだ遅いのか。
サンキュ
415デフォルトの名無しさん:2006/01/06(金) 00:22:18
>>414
いや、三項演算子ってジャンプするけどな。
それでも 0 が他と比べて早いと思う。
DSP とか、条件命令実行機能持った CPU だと条件ジャンプのコストはかなり低いし。

super scaler とか hyper threading でバリバリに最適化かかったら 1 が早いかもしれないけど、
十中八九 0 かと。

乗算はやっぱ遅い。
ただ、MMX 命令みたいに、複数の乗算を同時に出来る命令持った CPU もあるから、
そういうのだと積和演算なんかのスループットは結構早い。
416デフォルトの名無しさん:2006/01/06(金) 00:38:03
int32_t min5(int32_t a, int32_t b) {
 int32_t d = a - b;
 return a - (d & (~(d ^ (a^b)&(d^a)) >> 31));
}
417デフォルトの名無しさん:2006/01/06(金) 01:00:22
int32_t min6( int32_t a, int32_t b ) {

int32_t r[2] = { a, b };
return( r[a<b] );

}
418デフォルトの名無しさん:2006/01/06(金) 01:09:53
int32_t min7( int32_t a, int32_t b ) {
  if (MB_YES == MessageBox(NULL, "a は b より大きいですか?", "('A`)", MB_ICONINFORMATION |MB_YESNO)) {
    return a;
  } else {
    return b;
  }
}
419デフォルトの名無しさん:2006/01/06(金) 01:30:00
min7 は逆じゃないか?
420デフォルトの名無しさん:2006/01/06(金) 02:42:51
>>417
それ、メモリアクセスになって余計に遅かったりはしない?
あるいは最適化が効いて結局 0 と同じコードになるか。
421デフォルトの名無しさん:2006/01/06(金) 03:04:41
std::min つかえば、ライブラリ実装者が最適な実装を提供してくれる、
といいなぁ。
422デフォルトの名無しさん:2006/01/06(金) 05:40:16
CPUによっては条件ビットセットがあるから問答無用でmin0が速いべ。
423デフォルトの名無しさん:2006/01/06(金) 12:32:22
>>420
メモリアクセスってもスタックは大概キャッシュにあるだろ。
0 の方が速いが。
424デフォルトの名無しさん:2006/01/06(金) 12:52:39
PPCの命令セットには、「値の小さい方をとる」命令が含まれていたよ。
425デフォルトの名無しさん:2006/01/06(金) 22:26:33
この程度じゃパイプラインがストールしたりはしないのか。ためになったよ。
426デフォルトの名無しさん:2006/01/06(金) 23:36:22
こういうよくあるケースで躓くような設計はしないよね。
427デフォルトの名無しさん:2006/01/07(土) 00:04:44
for(i=0; i<1000; ++i) {
 for(j=0; j<100000; ++j) {
  k = rand();
  l = rand();
  test[j&0xFF] = min0(k,l);
 }
}
みたいな感じでやったら、北森Pen4 3.0G + VC7.1 Releaseビルド(/GB)で
5≒6<2<1≒3<4<0<<<<越えられない壁<<<<7
だった。/G7にすると2が最速
428デフォルトの名無しさん:2006/01/07(土) 00:08:07
>>427
さすがパイプライン深いな。
5が速いのは倍速ALUかな?遅いシフトも1回だけだし。

6はシンプルに分岐をなくすいい手だね。
429デフォルトの名無しさん:2006/01/07(土) 00:19:06
ほんと流石 Pen4 だな。
いろんな意味で。
430デフォルトの名無しさん:2006/01/07(土) 00:32:39
>>427
それぞれの実測値は?
7以外は測定誤差の範囲内だったりしないか?
ちゃんとQueryPerformanceCounterとか使った?
431デフォルトの名無しさん:2006/01/07(土) 00:49:13
俺はPentiumMで測ってみました。
VC++2003の/G6オプション。
>>427氏と同じコードで1ループ当たりのクロック数。

0:42clk
1:41clk
2:37clk
3:39clk
4:40clk
5:38clk
6:34clk

ランダムデータだから0が遅いんだね。
普通は分岐予測が効くだろうから実戦では0が速いんだと思う。
6は速いねえ。
コンパイル結果を見ると、6のr[2]はeaxとecxになってた。
つまりメモリアクセスをしていないから速い。
432デフォルトの名無しさん:2006/01/07(土) 01:00:23
>>431
eax と ecx は ID が1違いのレジスタってことなんかな?
433デフォルトの名無しさん:2006/01/07(土) 01:04:32
>>432
32bitのx86は8個の汎用レジスタがあって、espがスタックポインタな他は
どれも同じ種類のレジスタと考えて差し支えないと思いまんもす。
別にebxとesiに割り当てても速度や動作に違いは出ない。
434デフォルトの名無しさん:2006/01/07(土) 01:04:37
>>431
7は?
435デフォルトの名無しさん:2006/01/07(土) 01:08:04
>>434
僕がボタンを押すのに40clkとかの時間で済むと思いますか。
436デフォルトの名無しさん:2006/01/07(土) 01:08:11
>>433
いや、min6 が分岐じゃないから早いという理屈から察するに、
a < b の演算結果が 0 か 1 かという事実から、
条件分岐ではなく値の違いでレジスタを選択できなきゃ駄目でしょ。
そういうことじゃないん?
437デフォルトの名無しさん:2006/01/07(土) 01:14:03
>>436
その通り。。俺の勘違いですた。
メモリアクセスはその後でしています。
438427:2006/01/07(土) 01:16:30
>>430
timeBeginPeriod(1) & timeGetTime() で計りますた。
何回やっても、こんな傾向だから、誤差以上ではあると思う。

5 ≒ 6 < 2 < 1 ≒ 3 < 4 < 0
5015 5019 5040 5092 5084 5151 5563 (ms)

/G7にすると2が5000ms切って、最速なんだけど、コード見たら
dec eax が sub eax,1 に置き換わってるだけだった。
そんなに違うもん?
439デフォルトの名無しさん:2006/01/07(土) 01:18:38
>>435
頑張れ!
440デフォルトの名無しさん:2006/01/07(土) 01:20:42
>>438
Pentium4だと、decとsubでレイテンシが0.5clk違う。
まあ、1〜2%の差なら生まれてもおかしくない。

意外だが、0と6の差がPentiumMより少ないね。
441431:2006/01/07(土) 01:36:35
俺はサボってしまったが、427氏は7もちゃんと測ったんだろうか。
442デフォルトの名無しさん:2006/01/07(土) 01:38:24
そういえば、インラインに展開のされ方によってはどうなんだろう。

min0 が遅い理由、まあ Pen4 のパイプライン段数が糞多いのが直接の原因だけど、
普通は遅延分岐とかで多少マシになるでしょ。
入力がランダムだから予測は意味ないけど、遅延分岐なら。

min 関数の場合、遅延させるほど命令がないからどうしようもなくなってるわけで、
min 関数の前とかに別の処理とか入ってたらひょっとすると遅延分岐が効いてこないかな?
443デフォルトの名無しさん:2006/01/07(土) 01:43:50
>>440
Pen4 はよく知らないけど、普通は dec の方が早くないの?

Pen4 って内部的には算術命令を複数個並列処理してるんだっけ?
dec と sub を並列実行することで早くなってるとかでもないんかね?< /G7 で 2 が早くなるっての。
dec の演算器は全部使っちゃっててデータハザード起きてて、
それが sub に置き換えると(本来は sub の方が遅いけど、データハザード起こさない分)早くなるとか。
444デフォルトの名無しさん:2006/01/07(土) 01:48:14
>>442
遅延分岐って、フラグが確定するまで待つってこと?
x86で実装されてるの?

>>443
最近のCPUではdecもsubもほぼ変わらない。使うユニットも同じ。
命令長がdecの方が短いのがわずかに利点。
ただ、Pen4ではdecのが遅い。
これはパーシャルフラグの扱いがPen4では異なるため。
445デフォルトの名無しさん:2006/01/07(土) 01:56:54
実際に、分岐ミスでパイプラインの段数分損しないケースはある。
アウトオブオーダーして、フラグを決める命令と分岐命令を先に実行する。
分岐命令が早めに実行されれば、予測ミスが発覚するのも早くなる。
つまり分岐ミスのペナルティが減る。
446デフォルトの名無しさん:2006/01/07(土) 01:59:34
>>444
>>442 は何か勘違いしてたかも。流して。

dec の方が遅いんか。
CPU は昔 RISC と DSP 中心で勉強したんで Pen4 は結構異文化だわ。
447デフォルトの名無しさん:2006/01/07(土) 02:01:06
>>445
あっ、それそれ。
Pen4 ってアウトオブオーダー実行してるんだっけ?
フラグ決めと実際の分岐の間に命令挟むようなことしてたら、
インライン展開の結果次第では・・・という。
448デフォルトの名無しさん:2006/01/07(土) 02:01:09
>>445の続き。
まあ、「別の処理」がないとアウトオブオーダーできないけどね。

PentiumMでは、通常14clk程度のペナルティだが、少なくなることも多い。
ただ、どうやっても7〜9clkのペナルティはあった。
449デフォルトの名無しさん:2006/01/07(土) 02:04:40
PenPro以降のCPUはみんなアウトオブオーダーしてるよ。
ただ、この場合はさむものがないからねえ。
Pentium4ならminと次のrand()を並列実行できたりしてw
450デフォルトの名無しさん:2006/01/07(土) 02:07:27
>>448
min 関数単体でループ繰り返す限りには、「別の処理」なさ過ぎて >>445 みたいなのが全く役に立たないけど、
インライン展開後に「別の処理」があるようなコードでループすればどうなのかなぁと。

まあ、でも、予測の効かないランダムな値相手だとどうしても分岐は遅いのかな。
451デフォルトの名無しさん:2006/01/07(土) 02:17:10
>>450
なるへそ。
>>448のように、ランダムでもペナルティを半分くらいにはできるはずだけど。

でも実際は、普通は0が速いし、ランダムなら6使っとけば安心ということで
あんまり気にしなくてもいいのかもしれないけどね。
452デフォルトの名無しさん:2006/01/07(土) 02:23:18
ま、大体 CPU 依存だしねぇ。
Pen4 みたいに相当分岐に弱い環境でも10%くらいしか不利つかないんだと、
パイプラインの短いのなら普通は 0 が早そうよね。

2とか5は、よっぽど算術論理演算のクロックが短いか、
演算器が結構な数並列になってないと早くない気もするし、

6が使える条件も、0 か 1 かでレジスタを切りかえれないと駄目なわけだけど、
たいていの処理系ってそれできるんだっけ?
453431:2006/01/07(土) 02:28:42
int32_t min8( int32_t a, int32_t b ) {
 __asm{
  mov eax,a
  cmp eax,b
  cmovg eax,b
 }
}

8:38clk

インラインアセンブラを使ってみた。6に負けたorz

>>452
どっこいPentiumMでは分岐ありの0は30%も遅い。

>たいていの処理系ってそれできるんだっけ?
フラグを汎用レジスタに転送できればいいのだから
大概大丈夫でしょう。
454デフォルトの名無しさん:2006/01/07(土) 02:33:59
去年、これに似た件で計測した覚えが...
IA32系じゃなくMIPS系CPUだったので

int32_t min8( int32_t a, int32_t b ) {
 int32_t f = (a <= b);
 return (a & (-f)) | (b & (f - 1));
}

( と floatに対してはmin6 )を使ってみたが、
計ったら min0() のほうが速かった
455デフォルトの名無しさん:2006/01/07(土) 07:57:59
>>454
MIPS 系は2個しか触ってないけど、FPU 積んでて min.s が無い石があるんだね・・・
456431:2006/01/09(月) 02:59:06
コンパイラの出力を見ると、min6とかはインライン展開されていて
ほとんどレジスタだけで処理を済ませている。

それに対し>>453のmin8では、インライン展開はされているものの
展開先で、インラインアセンブラの範囲には最適化が全くかからないため、
無駄にメモリを介在することになってしまう。
457デフォルトの名無しさん:2006/01/22(日) 07:42:08
これが最適化ヲタの巣窟か
458デフォルトの名無しさん:2006/01/26(木) 22:01:58
これがオタに見えるって、どんな素人だよw
459デフォルトの名無しさん:2006/01/30(月) 08:23:22
AMDのプロセッサでもIntelコンパイラでコンパイルするとgccなどよりも高速なコードが生成されますか?
460デフォルトの名無しさん:2006/01/30(月) 13:20:30
>>459
AMDがIntelに対して起こした告訴理由の一つとして
「ICCにおいてAMDプロセッサを使ってコンパイルすると糞コードを吐く」
を主張している。

ttp://www.itmedia.co.jp/news/articles/0507/14/news031.html
461デフォルトの名無しさん:2006/01/30(月) 13:21:24
-AMDがIntelに対して起こした告訴理由の一つとして
+AMDがIntelに対して起こした訴訟の告訴理由の一つとして
462デフォルトの名無しさん:2006/01/30(月) 13:34:26
>>460
これって、コンパイルした実行ファイルを実行するときの話じゃなくて、
コンパイラの動作自体がCPU依存になってるってこと?
だとしたらとんでもないな。
463デフォルトの名無しさん:2006/01/30(月) 13:36:29
>>459
とりあえずSPECなんかみてるとOpteron+ICCの構成はいくらでもみつかる。
464デフォルトの名無しさん:2006/02/02(木) 06:18:46
>>463
劣化したコードにもかかわらずこれだけ出ているのはすごいな
465デフォルトの名無しさん:2006/02/02(木) 10:55:11
「ICCにおいてAMDプロセッサを使ってコンパイルすると糞コードを吐く」
のであれば、IntelCPUでコンパイルしてAMDCPUで実行しても
遅くならないんじゃまいか。
466デフォルトの名無しさん:2006/02/02(木) 11:26:01
>>465
実行時にCPUを判別して分岐する
467デフォルトの名無しさん:2006/02/02(木) 11:35:27
AMD向けの最適化を謳ってる商用コンパイラってPGIとPathScaleだよね。
MSVCとICCとGCCもいれて全部比較してみれたら面白そうだなぁ。
468デフォルトの名無しさん:2006/02/03(金) 02:17:18
>>427
これどうして、k, lをrand()にしているの?
min*()よりずっと重い処理になるけれど。
469デフォルトの名無しさん:2006/02/03(金) 09:53:14
>>468
ランダムにしないと分岐予測が当たっちゃうから。
まあ、ランダムにしたせいで分岐ペナルティの最も多い場合になるわけだが。
470デフォルトの名無しさん:2006/02/03(金) 10:41:17
k = i+j;
l = i-j;

にするとだいぶ結果が変わってくるな。
471デフォルトの名無しさん:2006/02/03(金) 10:53:33
>>460
全く同じOS構成、ICC構成で、CPUだけ違う環境を用意して
ICCが吐くコードをバイナリ比較すりゃいいじゃん。
472デフォルトの名無しさん:2006/02/03(金) 11:18:27
>>471
うそー、コンパイル環境で吐くバイナリが変わるのか?
473デフォルトの名無しさん:2006/02/03(金) 13:07:17
手元のPowerPC G4(OSX)とWindowsXP(cygwin)で試してみた。
コンパイラがgccって事もあって、どちらもmin0が一番速かった。

ちなみにどちらも最適化オプションは同じ(-O4)で、
コンパイラのバージョンは
OSX gcc 3.3
cygwin gcc 3.4.4
474デフォルトの名無しさん:2006/02/06(月) 16:49:32
>>472
出鱈目だろ。
実行時に判別して〜云々は、よくマニュアル読んでないだけか、ただの言いがかり。
たとえば/QaxNとかでビルドすると、SSE2の使用有無にかかわらずPentium 4でしか最適化された
パスを通らないコードができるがそれは当たり前の動作。AMDのCPUであろうがなかろうが跳ねられる。

CPU毎の最適化を使いつつICCのスタートアップルーチンを使わない手ならいくらでもあるけどな。
一番簡単なのは、最適化対象の関数だけターゲット数分別名で作って、ファイルごとにコンパイルオプション
変えて(/G6, /G7, /QxK, /QxN, /QxP, /QxB, ....)専用にコンパイルし、全部リンクする。
自前で関数テーブルを作ってやる必要があるが、CPUIDで自動判別させるのを自前でやるなり、
ユーザーに選ばせるなりできる。

信用しきれないなら/FAでasmコード生成してそいつをVC++で利用するのも悪くないお
475デフォルトの名無しさん:2006/02/12(日) 15:28:25
インリンをつけた関数がインリン化されやすくなるようにするにはどのようなことに気をつければいいですか?
476デフォルトの名無しさん:2006/02/12(日) 17:05:31
分岐・ループしない
大きくない
他のインリンされそうにない関数よばない
477デフォルトの名無しさん:2006/02/12(日) 17:35:45
>>475
>476は血迷っているので信じないように。
コンパイラによって違うから、一概に言えないとしか言いようがないのがinline化。
例えば、分岐やループがあろうが標準関数を呼ぼうがinline化される環境ならinilne化される。
478デフォルトの名無しさん:2006/02/12(日) 20:14:39
forceinlineみたいのはいかんのん

あとエロテロリストにきくのが一番いいとおもうけど
479デフォルトの名無しさん:2006/02/12(日) 23:36:35
血迷っているのは>>477のほうだな。
もう一度>>475が何を訊ねているのかを読むべき。
480デフォルトの名無しさん:2006/02/12(日) 23:46:43
>>479
477は日本語が不自由なんだよ
481デフォルトの名無しさん:2006/02/12(日) 23:57:35
ん?>>477は環境によって違うと言っているだけだろ?
482デフォルトの名無しさん:2006/02/13(月) 00:17:54
>>477>>481は屁理屈気違いなので放置の方向で。

483デフォルトの名無しさん:2006/02/13(月) 02:57:02
そいつの存在は他スレでも確認した。
そろそろプギャーとか言い出すぞ。
484デフォルトの名無しさん:2006/02/13(月) 07:10:20
インテル C++コンパイラ9.0での話だけどSIMDのintrin命令を多用したコードでは
-O3 -Qipioより-O2 -Qip -Qunroll0で最適化したほうがなぜか速いケースがある。
485デフォルトの名無しさん:2006/02/13(月) 11:10:28
>>475 に便乗しますが
菊地美香をなんとかインリン化できないものでしょうか?
486デフォルトの名無しさん:2006/02/13(月) 12:10:17
>>485
カプセル化されてるから難しい
487デフォルトの名無しさん:2006/02/13(月) 17:20:36
インド人をカリー化するほうが簡単だな
488デフォルトの名無しさん:2006/02/14(火) 14:39:32
ヨーダ「フォースを使うのだ」


#define inline __forceinline
489デフォルトの名無しさん:2006/02/14(火) 17:38:57
つうか、C/C++も中間言語までのコンパイルにして実行時にCPUにあわせて最適化かけるで良いじゃないか
490デフォルトの名無しさん:2006/02/14(火) 17:46:52
よくねーよハゲ(^^)
491デフォルトの名無しさん:2006/02/14(火) 18:07:00
>>489
つC++/CLI
492デフォルトの名無しさん:2006/02/14(火) 18:08:20
>>489
今となっちゃIA-32のアセンブラ自体中間言語みたいなもんだ
493デフォルトの名無しさん:2006/02/14(火) 19:26:00
>>492
ずいぶんと古い今だな。
494デフォルトの名無しさん:2006/02/26(日) 07:30:31
大発見!!!スイッチで12分岐以上位だとどれも速度が変わらないぞ!
495デフォルトの名無しさん:2006/02/26(日) 09:13:22
だよね。(12分岐と言う数字はケースバイケースだと思うが)

むかしは条件判定もったいないとかで関数ポインタ駆使したりと
小手先なことしてたが、最近はスイッチで十分だと。

言語から仮想関数とかの支援があればそれを使うのも結構だけど、
分岐そのものがその場に書いてあるスイッチやバカチョンif判定
書いてあるスイッチはやはり後で見て分かりやすい
496デフォルトの名無しさん:2006/02/26(日) 09:32:20
caseの値が連続しているswitchは、jumptableに展開するコンパイラたくさんありますよ。
497デフォルトの名無しさん:2006/02/26(日) 10:32:19
c、c++のcase文って複数纏めて指定できないから嫌
連続する数値は
case 'a' to 'z': とかできたらいいのに
498デフォルトの名無しさん:2006/02/26(日) 10:41:24
複数が狭い範囲なら
case 0:
case 1:
case 2:
case 3:
処理
499デフォルトの名無しさん:2006/02/26(日) 12:20:27
>>496
連続してなくても(半ば強引に)展開するコンパイラもあるね。

>>497
case 'a': case 'b': ... case 'z':
を自動生成させてはいかが?w

>>495
半島人を中途半端に馬鹿にする発言はよくない。
きちんと、「馬鹿でも朝鮮人でもできるような単純な判定」と書きましょう。
500・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/02/26(日) 14:42:43 BE:491415168-
>>497
GCCの独自拡張で to → ..
501デフォルトの名無しさん:2006/03/01(水) 13:57:02
>>499
「バカチョン」は朝鮮人とは何の関係もない言葉なのだが…。
502デフォルトの名無しさん:2006/03/01(水) 14:02:27
>>501
その言葉は「バカでもチョンでも」から来たとする説と
「バカでもチョンと押すだけで」から来たとする説の二つがある。
前者が存在する時点で使うのをためらうべき言葉だとは思わないか?
503デフォルトの名無しさん:2006/03/01(水) 14:11:15
>>502
「『ちょん』は明治時代には日本語として存在していて
 バカや間抜けと同義。」らしい。
まあ、言葉狩りに意味があるとも思えんが。
504デフォルトの名無しさん:2006/03/01(水) 14:41:07
>>503
二つ意味があるってだけでどっちにしろ同じことじゃないかな?
起源について二つの説がある「バカチョン」という言葉の問題か
二つの意味を持つ「ちょん」という言葉の問題かってだけで。

まあ最適化とは関係ないからそろそろ次の人どうぞ。
505デフォルトの名無しさん:2006/03/01(水) 14:46:04
       \
 お そ .い ヽ
 か の や  |
 し  り  `  ,. -──- 、
 い .く   /   /⌒ i'⌒iヽ、
    つ /   ,.-'ゝ__,.・・_ノ-、ヽ
    は i ‐'''ナ''ー-- ● =''''''リ      _,....:-‐‐‐-.、
      l -‐i''''~ニ-‐,....!....、ー`ナ      `r'=、-、、:::::::ヽr_
 ̄ \ヽー' !. t´ r''"´、_,::、::::} ノ`     ,.i'・ ,!_`,!::::::::::::ヽ
    ヾ、 ゝゝ、,,ニ=====ニ/r'⌒;    rー`ー' ,! リ::::::::::::ノ
       i`''''y--- (,iテ‐,'i~´,ゝ'´     ̄ ̄ヽ` :::::::::::ノ
       .|  !、,............, i }'´    _   、ー_',,...`::::ィ'
     ●、_!,ヽ-r⌒i-、ノ-''‐、    ゝ`ーt---''ヽ'''''''|`ーt-'つ
        (  `ーイ  ゙i  丿   ;'-,' ,ノー''''{`'    !゙ヽノ ,ヽ,
        `ー--' --'` ̄       `ー't,´`ヽ;;;、,,,,,,___,) ヽ'-゙'"
                       (`ー':;;;;;;;;;;;;;;;ノ
                       ``''''''``'''''´
506デフォルトの名無しさん:2006/03/01(水) 16:34:00
ここは放送倫理に縛られる場所じゃないから、結局は自己責任で使え。
ただ、本人には、反駁があってバカにされたあげくにスレが荒れたら責任を感じてもらいたい。
507デフォルトの名無しさん:2006/03/01(水) 16:49:11
スレは全然最適化されてないな
508デフォルトの名無しさん:2006/03/01(水) 18:33:18
>>507
来るべき質問を予測して投機的に回答しておいたり、引用はinline展開したりするべきだな。
509デフォルトの名無しさん:2006/03/01(水) 19:44:11
差別用語として意識しつつ、敢えて使う。これ、最強。
510デフォルトの名無しさん:2006/03/01(水) 19:46:41
それは思考停止状態のサル並ということだが、たしかに最強だな。
511デフォルトの名無しさん:2006/03/01(水) 19:52:52
>>510
思考停止はお前。
512デフォルトの名無しさん:2006/03/01(水) 20:38:10
>>508
同趣旨のレスは一箇所で定義しておいて、他で参照するようにするとか。
513デフォルトの名無しさん:2006/03/01(水) 21:30:41
>>511
脊髄反射はお前。
514デフォルトの名無しさん:2006/03/02(木) 00:10:07
ここで脊椎反射ですよ
515デフォルトの名無しさん:2006/03/02(木) 11:35:53
それなら俺は骨髄反射
516デフォルトの名無しさん:2006/03/02(木) 12:02:14
脊髄反射割り込みのオーバーヘッドを最適化したいのですが
517デフォルトの名無しさん:2006/03/02(木) 12:03:10
関係ないけどすっとんで脊髄反省しに来ました。
518デフォルトの名無しさん:2006/03/02(木) 12:45:25
ずいずいずっころばしのスレはここですか?
519デフォルトの名無しさん:2006/03/02(木) 14:14:04
>>518
そうです。よくこのスレの秘密がわかりましたね。
みんなで暗号化して一見C,C++の話やちょんの話を
しているように見せかけて実はずいずいずっころ
ばしのことを延々と話していたんですが。
520デフォルトの名無しさん:2006/03/02(木) 15:10:07
ごまみそずい
521デフォルトの名無しさん:2006/03/02(木) 15:46:21
これはもうだめかもしれんね。
522デフォルトの名無しさん:2006/03/02(木) 16:20:18
>>519
 う
 ん

   こ を延々と していた


こうですか?わかりません!
523デフォルトの名無しさん:2006/03/02(木) 22:40:58
>>522
  で
  な
  い
  の
524デフォルトの名無しさん:2006/03/02(木) 23:40:41
www
525デフォルトの名無しさん:2006/03/03(金) 00:37:32
冗長だったのが最適化された!
流石プロハカー!
526デフォルトの名無しさん:2006/03/03(金) 22:30:02
VC8とか、SSE最適化しても4次元ベクトルとかをSIMD計算してくれなくてガッカリ。
527・∀・)っ[F32vec4] ◆Pu/ODYSSEY :2006/03/03(金) 22:47:26
アレはx87演算をSSEのスカラ演算に置き換えるものなので。

528デフォルトの名無しさん:2006/03/03(金) 23:36:59
うーん。
SSE2とか使うのは難しくないけど、
それでより効率よく演算できるようにしようとすると、俺のレベルじゃ無理だ。
529デフォルトの名無しさん:2006/03/04(土) 02:49:39
C、C++とは関係無い話だな。
しかも効率ってSSEじゃなくてメモリアクセスのほうが問題になるだろ。
530デフォルトの名無しさん:2006/03/04(土) 08:07:32
>>526
Intel C++ Compilerならある程度の自動ベクタライズをしてくれる。
でも、いろいろコンパイラに指示しなくてはならないし複雑なものには対応してくれない。
結局は自分で直接SIMD命令を書くのが効率がよい。
アセンブラで書くのが面倒なら組み込み命令(xmmintrin.h)を使ってみるといい。
531デフォルトの名無しさん:2006/03/04(土) 09:19:08
ハートで感じるパイプライン講座ってないかな...
532・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/03/04(土) 14:06:41
*mmintrin.hとそのラッパーの*vec.h使っておけばいい。
パイプラインを考慮したスケジューリングはコンパイラ任せでも十分速度出る。
むしろハードウェアのレジスタリネーミングやOoOである程度畳み込みやってくれる。
533デフォルトの名無しさん:2006/03/04(土) 20:54:53
>>530
でも、その最適化って年末あたりに出る次の世代のx86じゃ使えないんだろ
534デフォルトの名無しさん:2006/03/04(土) 21:05:50
民生機用CPUとしてベクトル演算機がダイ上に実装される日はくるか
535デフォルトの名無しさん:2006/03/04(土) 23:05:03
>533
MMXはx64で使えなくなってるね。 SSE系が使えなくなるって話はまだ聞いてないけど。

>526
>530が言ってるようにxmmintrin.h使うといいよ。
ICCとVC6以降で使えたと思う。 MSDNに英語のドキュメントがあるから参考にするといい。
(ドキュメントはC++ LanguagesのCompiler Intrinsic以下)
レジスタ割付を考えなくてすむので、アセンブリで書くよりは大分楽になる。
// あるいは、Direct3Dで用意されてる各構造体を使うという手も。 確か自動的にSSE使ってくれたと思う。
536・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/03/04(土) 23:07:54
>>535
mmintrin.h使うとIA64でもx64でも64bit汎用整数使ったコードに展開される。
537デフォルトの名無しさん:2006/03/05(日) 01:17:50
>536
あれ? おいらが試したときはリンクエラー出たんだけど>MMXのintrinsic
538デフォルトの名無しさん:2006/03/05(日) 04:12:15
>>534
今のショートベクトルよりでかいベクトル演算器がのることはないだろ。使い道ないし。
539デフォルトの名無しさん:2006/03/05(日) 04:20:17
すみません、こちらのスレでこの方を引き取って頂けませんか?
http://pc8.2ch.net/test/read.cgi/tech/1140510670/117-
540・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/03/05(日) 04:28:31
>>537
ごめん、ビット論理(pandとかpxor)やシフトとかのごく一部だけかもしれん。また機会があったら試してみる。

リンクエラー?コンパイルエラーじゃなくて?
541デフォルトの名無しさん:2006/03/05(日) 04:30:20
>>539
スレ違い
542デフォルトの名無しさん:2006/03/05(日) 04:36:54
要約すると、彼はいま1024*768画像の合成に5秒かかっていて、
それを100msで処理したいそうです。
543・∀・)っ-○●◎- ◆Pu/ODYSSEY :2006/03/05(日) 04:42:52
どうやれば5秒もかかるんだ?

実は3次元なんじゃね?XGA×奥行きwww
544デフォルトの名無しさん:2006/03/05(日) 06:15:33
リンク先読まずにレスするが
なんで糞質問糞レスをしてる暇は湯水のようにあるくせに
4900ms程度を待てないようなバカが平気で生きてるんだろう?

ホント避妊は大事だよな。
545デフォルトの名無しさん:2006/03/05(日) 10:06:25
自分の頭で計算して5秒かかるのを
コンピュータに100msでやらせたいってんなら
ある意味すげえけどな。
546デフォルトの名無しさん:2006/03/05(日) 11:00:37
脳と比べりゃもっとはえーだろ
547デフォルトの名無しさん:2006/03/05(日) 12:52:12
>>546の脳はノイマン型
548デフォルトの名無しさん:2006/03/05(日) 13:51:07
ざっと読んだだけだがAPIコールしすぎとかキャッシュコヒーレンス無視すんなとか
基本的なとこでずれてる。
549デフォルトの名無しさん:2006/03/07(火) 02:21:31
>>539
質問スレに誘導した方がいいね。

内容うんぬんより、質問者の質問の仕方に問題有りそうだ。
『こうすれば解決するはず』と思いこんでいて解答者が
求める情報を出し渋るパターン。
他、解答者が求める情報を『問題とは関係無い』と出さなかったり。

まだ続きそうだったら↓のスレに案内するのはどうかな。
(3)(4)はちょっと失礼なので(1)(2)あたりで。

(1)C統合・質問スレッド
http://pc8.2ch.net/test/read.cgi/tech/1068359871/l50

(2)すれ立てるまでもない質問はここで 第74刷
http://pc8.2ch.net/test/read.cgi/tech/1140269442/l50

(3)はきだめC/C++下級者の質問箱
http://pc8.2ch.net/test/read.cgi/tech/1124256027/l50

(4)【漏れは】猫でもわかる質問スレ【猫以下です】
http://pc8.2ch.net/test/read.cgi/tech/1054813207/l50
550デフォルトの名無しさん:2006/03/07(火) 06:35:56
>>549
>(1)C統合・質問スレッド
>http://pc8.2ch.net/test/read.cgi/tech/1068359871/l50

ちょwwwwそれC#のスレだからwwwww

# なんかスレタイに"#"を使うと消えちゃうらしいw
551デフォルトの名無しさん :2006/03/13(月) 11:13:35
volatile
552デフォルトの名無しさん:2006/03/14(火) 04:12:59
それの次スレ作る時は

C・しゃーぷっ 統合質問スレッド

で解決だな
553デフォルトの名無しさん:2006/03/14(火) 11:17:21
>552
なにかデジャブを覚えると思ったらおじゃ魔女だったorz
TextSS のWindowsXP(Professional)64bit対応化おながいします

もしくは64bitにネイティブ対応したテキスト置換ソフトありますか?

そういや64bitにネイティブ対応している2chブラウザてありましたっけ?
555デフォルトの名無しさん:2006/03/19(日) 01:46:21
スパム乙
556デフォルトの名無しさん:2006/03/29(水) 17:45:01
unsignedをつけると高速化する可能性はありますか?
557デフォルトの名無しさん:2006/03/29(水) 18:12:19
あります
558デフォルトの名無しさん:2006/03/29(水) 18:30:28
可能性は常にある。
559デフォルトの名無しさん:2006/03/29(水) 18:38:31
inlineですら可能性に過ぎないからな。
560デフォルトの名無しさん:2006/03/30(木) 00:05:50
でもまあ、ほとんどの場合変わらんだろ、符号有無じゃ
561デフォルトの名無しさん:2006/03/30(木) 00:11:42
いや、比較命令が少なく済む可能性がある。
                  ~~~~~~~
562デフォルトの名無しさん:2006/03/30(木) 02:02:08
while(i > 0) はunsignedだと速くなる可能性はあるな。
563デフォルトの名無しさん:2006/03/30(木) 03:24:09
while(i>=0) なら確実に早くなるぞ。
564デフォルトの名無しさん:2006/03/30(木) 03:26:04
いや、CPUの命令セットによるから、確実はあり得ない。
565デフォルトの名無しさん:2006/03/30(木) 08:34:15
>>564
お前ならいったいどんな条件を機械語で書くのか、小一時間問い詰めたい。
566デフォルトの名無しさん:2006/03/30(木) 08:41:56
>>564
例えば条件分岐の非成立の直後のみ無条件分岐の予測に成功する処理系とかか
存在するのか?
567デフォルトの名無しさん:2006/03/30(木) 09:09:04
っていうか、コンパイラの最適化依存だから、確実でもないだろう。
568デフォルトの名無しさん:2006/03/30(木) 09:50:46
最適化というオプションが備わってるのに、これで
条件分岐のコード吐くようじゃなんの意味もないな
569デフォルトの名無しさん:2006/03/30(木) 10:00:08
ただ反論したいだけちゃうんかと
570デフォルトの名無しさん:2006/03/30(木) 10:02:24
いや、逆に賢いコンパイラでループを展開するなんて可能性も。
571デフォルトの名無しさん:2006/03/30(木) 10:03:48
無限ループを展開?
572デフォルトの名無しさん:2006/03/30(木) 10:04:12
ごめん、よく見てなかったw
573デフォルトの名無しさん:2006/03/30(木) 10:45:50
563を否定する可能性を見つけた。

Z80系のCPUは無条件ジャンプよりも、条件ジャンプの方がクロックが短い。
(条件成立時は同じで非成立時が短い)

do { i--; } while(i >= 0);

これがZ80ではsignedの方が速い可能性がある。

まぁ、ループを抜けるとこまで考えなくても、Z80では無条件ジャンプも
条件ジャンプの成立時もクロックが同一なので、ループの判定が
コストフリーの場合は速くはならないな。
574デフォルトの名無しさん:2006/03/30(木) 10:49:32
575デフォルトの名無しさん:2006/03/30(木) 10:56:56
>>556
このスレでは、一般論は無駄。
まずやってみろ。
576デフォルトの名無しさん:2006/03/31(金) 22:08:55
unsigned int a,b;

b=a/2;
と書くと、シフトにしてくれる
signedだと無理。
577デフォルトの名無しさん:2006/03/31(金) 22:37:38
>>576
お前の使っている処理系では、だな。
578デフォルトの名無しさん:2006/03/31(金) 23:03:23
>>576
日記乙。
579デフォルトの名無しさん:2006/03/31(金) 23:40:14
だから可能性なんだろ?
580デフォルトの名無しさん:2006/03/31(金) 23:44:07
>>577
意味わかってる?
581デフォルトの名無しさん:2006/03/31(金) 23:54:54
実際にそういう処理系が存在したので
可能性がある、という意味では必要条件を満たした
582デフォルトの名無しさん:2006/03/32(土) 02:26:30
"arithmetic shift" でググってみよう
583デフォルトの名無しさん:2006/03/32(土) 11:31:16
Cでは
-2わる2=-1
-3わる2=-1
だけど、signed charで
-2 = 0xfe,
-3 = 0xfd
でその算術シフトが
0xfe >> 1 = 0xff = -1
0xfd >> 1 = 0xfe = -2
で結果が違うからね。
unsignedなら論理シフトと一致。
signedでブランチなしのシフトを使った2の割り算は、
(n+((unsigned)n>>(bit数-1)))>>1
かな
584デフォルトの名無しさん:2006/03/32(土) 11:43:57
VC++ 7.1でのコンパイル例。

int divide_by_two(int n)
{
return n / 2;
}
mov eax, DWORD PTR _n$[esp-4]
cdq
sub eax, edx
sar eax, 1

unsigned int unsigned_divide_by_two(unsigned int n)
{
return n / 2;
}
mov eax, DWORD PTR _n$[esp-4]
shr eax, 1
585デフォルトの名無しさん:2006/03/32(土) 13:41:04
もうこの話題やめないか?w
大して意味のある話でもないし。
586デフォルトの名無しさん:2006/03/32(土) 14:06:05
たしか、2進数を使ってない奴は、昔に組み込み系であったような記憶があるが、
まあ、普通の人はそんな事は気にしなくても大丈夫だ。

そういう結論でいいだろ。
587デフォルトの名無しさん:2006/04/02(日) 13:14:11
負数の除算の丸めは未定義じゃなかったっけか?
C99で初めて定義されてた記憶があるんだが。
588デフォルトの名無しさん:2006/04/03(月) 07:53:51
未定義ではなく処理系定義
589デフォルトの名無しさん:2006/04/03(月) 11:33:51
負数の除算如きでいちいち鼻から悪魔が出てきたんじゃ堪らんなあ。
590デフォルトの名無しさん:2006/05/07(日) 08:35:07
1.
*address = data;
address++;
*address = data;
address++;
*address = data;
address++;
*address = data;
address++;



2.
address[0] = data;
address[1] = data;
address[2] = data;
address[3] = data;
address += 4;

の処理があったとして、これをループ処理を行った場合、1と2ではどちらが速いでしょうか?
591デフォルトの名無しさん:2006/05/07(日) 08:36:25
1.
MOV R1, @-R4
MOV R1, @-R4
MOV R1, @-R4
MOV R1, @-R4


2.
MOV R1, @R4
ADD #4, R4
MOV R1, @R4
ADD #4, R4
MOV R1, @R4
ADD #4, R4
MOV R1, @R4
ADD #4, R4


3.
MOV R1, @R4
MOV R1, @(4, R4)
MOV R1, @(8, R4)
MOV R1, @(12, R4)

ではどれが一番速いでしょうか?
592デフォルトの名無しさん:2006/05/07(日) 08:38:05
x86じゃないです
593デフォルトの名無しさん:2006/05/07(日) 09:23:32
>>590
速度は実測が基本。

CPU とコンパイラの組み合わせで結果が違うだろうから、一般的なことは言えない。
594デフォルトの名無しさん:2006/05/07(日) 21:56:20
色々試しましたところ、
メモリをクリア&確認する際に

1.
アドレスに0をセット
0になってるかORしてチェック
アドレスを加算
以下サイズ分ループ

2.
アドレス+サイズを算出(終了アドレス+1)

アドレスを減算
アドレスに0をセット
0になってるかORしてチェック
以下サイズ分ループ

1と2で、やってることは似たようなもののはずなのに(ただ単にアドレスを加算してるか減算しているかの違いぐらい)
なぜか処理速度(サイクル数)が異なってました。

原因として何が考えられますか?
595デフォルトの名無しさん:2006/05/07(日) 22:02:40
>>594
減算にするとループの終了判定が 0 との比較になるので
早くなることが、昔はよくあったものだ。

今時のコンパイラだと最適化かければ差はなくなると思ってたんだが、
どんなコンパイラ使ってんの?その前に最適化かけてないとか?

あとな、
「アドレスに0をセット」はわかりにくい。
文脈から「アドレスの指す位置に0をセット」と読み取るのに時間がかかった。
596デフォルトの名無しさん:2006/05/07(日) 22:09:01
すみません、言葉足らずでした。
ちなみに終了条件はサイズが0になっているかなので
アドレスの加算や減算とは特に関係はないと思っています。

>どんなコンパイラ使ってんの?その前に最適化かけてないとか?
コンパイラはSuperH用のコンパイラでSHCというものの最新版です。
最適化はスピード優先でやっています。

アドレスの加算と減算に処理速度の違いはあるのでしょうか・・・
(実際に試した感じでは違いがありました)
597デフォルトの名無しさん:2006/05/07(日) 22:21:03
>>596
速度は実測が基本。
「試した感じ」ってなんだよ。やる気あんのか?

まだ気になるなら、まずはリストファイル吐かせて
アセンブリソースを確認するのがいいだろう。

SuperH は詳しくないけど、書き込み+インクリメントが1命令にできて、
書き込み+デクリメントは1命令にできないとか?
598デフォルトの名無しさん:2006/05/07(日) 23:35:30
>>594
この部分、

> アドレスに0をセット
> 0になってるかORしてチェック

(*addr) = 0;
if ((*addr | 0) != 0)

ってことですか。 それとも

(*addr) = 0;
if ((addr | 0) != 0)

でしょうか。
*何が* 0なのか解りません。
599デフォルトの名無しさん:2006/05/08(月) 00:30:56
ようは

unsigned long temp = 0;

*address = 0;
temp |= *address;
address++;
これをサイズ分

もしくはaddressを最初にaddress += size;を行い、終了アドレス+1を算出後
address--;
*address = 0;
temp |= *address;
これをサイズ分

上記の処理を行ったとき、減算のほうが処理が早かったのです。
クリアサイズは
1024バイトで17サイクルの差
4096バイトで60サイクルの差
でした。
600デフォルトの名無しさん:2006/05/08(月) 00:34:27
>>599
address の型に volatile 付いてるか?
そうじゃなきゃ temp |= *address は最適化で消えるぞ。
601デフォルトの名無しさん:2006/05/08(月) 00:39:39
とりあえず、アセンブラコードで消えないように最適化の設定はしましたので大丈夫です

ようは、アセンブラコードを見た際に
アドレスを加算しながら先頭アドレスから終了アドレスまで処理を行うのと
アドレスを減算しながら終了アドレスから先頭アドレスまで処理を行うので
なぜ速度が変化するのかがアセンブラコード上ではわからなかったのです。

MOV @R1+, R2

MOV R1, @-R2
の違いでサイクル数が変わる理由です。
値をセット後アドレス加算と
アドレス減算後値をセットでなぜサイクル数が変わるのか・・・
CPUの問題でしょうか?
602デフォルトの名無しさん:2006/05/08(月) 03:45:30
( ゚ρ゚)ポカーン
603デフォルトの名無しさん:2006/05/08(月) 06:35:12
>>601
君の場合、そういうもんだと思って使え
理由を理解するにはまだ早い。
604デフォルトの名無しさん:2006/05/08(月) 08:07:23
というより、「回答者を気取るにはまだ早い」人達が
こりゃまずい、手に負えない、でも答えられず放っておくのも格好悪い、と考え、
まるで質問者に問題があるかのような(でもどう問題があるかは言えない)雰囲気を
頑張って作り出そうとしている、というところですかね :-)
605デフォルトの名無しさん:2006/05/08(月) 08:29:43
だったら君が答えてやれ。と言う事になる。
606デフォルトの名無しさん:2006/05/08(月) 08:33:59
なにが「だったら」なのか意味不明ですね。
嫌なことを指摘されたので慌てて焦点を変えてみたというところですかね :-)
607デフォルトの名無しさん:2006/05/08(月) 08:58:37
頼む、教えて下さい。
608デフォルトの名無しさん:2006/05/08(月) 09:10:29
>>606
お前のせいでさっき食ったソバ全部吐いちまったじゃねーか。
609デフォルトの名無しさん:2006/05/08(月) 13:25:17
おろろろろろ
610デフォルトの名無しさん:2006/05/08(月) 13:59:19
>>608
口の中にあるもの全部じゃなく、胃の中全部かいな。
そりゃ難儀やったのう。
611デフォルトの名無しさん:2006/05/08(月) 15:36:17
基地外が住み着いたか。
612デフォルトの名無しさん:2006/05/08(月) 15:44:13
自己紹介乙
もう帰っていいよ
613デフォルトの名無しさん:2006/05/08(月) 20:50:51
・・・で結局結論は誰もわからないっと。
614デフォルトの名無しさん:2006/05/08(月) 23:34:40
>>599
> これをサイズ分
ってあっさり書いてるけど、ループなんだからここがキモなんじゃ?
他にも一度で書くのは1バイトなのか4バイトなのか、とか。キャッシュの乗り方が
違ってくるし。
SHはワード未満のバイト単位のアクセスにペナルティがあったりしない?

>MOV @R1+, R2
>と
>MOV R1, @-R2
>の違いでサイクル数が変わる理由です。

と書いてるけど

>値をセット後アドレス加算と
>アドレス減算後値をセットでなぜサイクル数が変わるのか・・・

命令だけでなくて順序も違ってるし。パイプラインがストールするんじゃなくて?
どちらかというと、アドレス生成後にストアする方がペナルティありそうだけど。
615デフォルトの名無しさん:2006/05/08(月) 23:42:31
>>601
http://japan.renesas.com/fmwk.jsp?cnt=superh_family_landing.jsp&fp=/products/mpumcu/superh_family/
↑ここからたどったドキュメントにはアドレスをデクリメントしながら書き込む命令は
見当たらなかった。597 が正解なんじゃないかと思うんだけど、コンパイラの吐いた
アセンブラコード見たんだよな?
ほんとで MOV R1, @-R2 なんて命令あったか?
616615:2006/05/08(月) 23:44:47
ごめん。よく見たら
アドレスをデクリメントしながら書き込む命令と
アドレスをインクリメントしながら読み込む命令
があった。

アドレスをインクリメントしながら書き込む命令はないってことで、
インクリメントのほうが遅くなるんじゃね?
617デフォルトの名無しさん:2006/05/09(火) 15:50:12
>アドレスをデクリメントしながら書き込む命令と
>アドレスをインクリメントしながら読み込む命令

PUSH / POP か。
618デフォルトの名無しさん:2006/05/09(火) 18:08:54
昔々、PC-8801とかで、高速に画面を書き換えるために
push を使ったというのを聞いたことがある。
619デフォルトの名無しさん:2006/05/09(火) 22:00:02
>>617
機能はそのとおりだけどニーモニックは MOV だよ。
620デフォルトの名無しさん:2006/05/10(水) 01:00:29
( ゚д゚)ポカーン
621デフォルトの名無しさん:2006/05/10(水) 01:19:07
>>618 Z80でいっぱい使った。
622デフォルトの名無しさん:2006/05/10(水) 23:29:01
const指定で最適化が促進化される理由ってのは何でなんでしょう?
623デフォルトの名無しさん:2006/05/10(水) 23:36:43
>>622
const 修辞によって値が変わらないという前提を最適化機が得ることによって、
その値を使った式を定数の畳み込みに組み込む機会が増えるから。
624デフォルトの名無しさん:2006/05/11(木) 00:15:37
恥ずかしながら、定数の畳み込みというものをはじめて知りました。

[constなし]
int X = hogehoge;
int Y = 0;
X += Y;
↓↓↓↓↓↓↓
MOVE PTR[X] ER1;
MOVE PRT[Y] ER2;
ADD ER1 ER2;

[constあり]
int X = hogehoge;
const int Y = 0;
X += Y;
↓↓↓↓↓↓↓

MOVE PTR[Y] ER2;
ADD #hogehoge ER2;

アセンブラがわからないので上に例は適当です。どこかで定数使ったほうが早くなる項があるってことで理解しました。
ありがとうございました。
625デフォルトの名無しさん:2006/05/11(木) 00:31:33
後は、関数の引数、特にポインタ、をconst指定すれば、
関数呼び出しの後でも、メモリが書き換えられてないことが期待できるから、
メモリからのロードをサボることができるなど。
626デフォルトの名無しさん:2006/05/11(木) 00:33:18
>>625
C にはグローバル変数などがあるので、一般的にそれはできない。
しかし const にまつわる一般的な誤解の一つでもある。
627デフォルトの名無しさん:2006/05/11(木) 01:46:06
ふーむふーむ、にゃるほど。
もう一個質問なのです。
最適化目的ならば、constはこういう時に使えってものはあるのでしょうか?
例えば、

#define HOGEHOGE (2)
(中略)
const int temp = HOGEHOGE;

↑のような場合であれば、畳込みは起きるだろうなあと思うのです。
しかし、const宣言された変数の内容が動的に決まる場合にも、
定数の畳込みが起きる場合というのはあるのでしょうか?
例えば、

const int temp = pHoge->getHogeHoge();

コンパイラにここまでの解析能力があるのかってのが疑問です。
とりあえず、コンパイラが何をするのかわからないから、値が不変の変数は常にconst修飾しておくべきなんですかね?
628デフォルトの名無しさん:2006/05/11(木) 01:54:49
>>627
「最適化を目的に const を使うな。」という言葉を贈っておく。
629デフォルトの名無しさん:2006/05/11(木) 01:57:28
>>627
規格上は、その呼び出しが定数に最適化できれば、さらに畳み込むことは可能。

畳み込みじゃないが、下の temp のように const つきのオブジェクト定義が見えていれば、
たとえ &temp のようなポインタを取っていても >>625 の言うような
関数をまたぐ不変性が最適化に利用できる。

でも const は最適化への効果よりメンテナンス性への効果のほうがはるかに大きい。
おまけで最適化の助けになることもあるよ程度に考えたほうがいい。
630デフォルトの名無しさん:2006/05/11(木) 02:04:21
>628 >629
なるほどなるほど。ただ、健全に動いているソース部分に手を加えずに、
宣言部分にちょちょっと手を加えただけで、速度が改善できればなあ、って人情で許してください。
631デフォルトの名無しさん:2006/05/11(木) 02:21:48
思うほど差はないとおもわれ
632デフォルトの名無しさん:2006/05/11(木) 02:30:30
っていうか、ちょっと手を加える以前にconstでいいのは
最初からconstで宣言しておこうよ。
633デフォルトの名無しさん:2006/05/11(木) 02:35:52
そもそもconstって概念が駄目だね。
constな変数が基本で、
書込できる変数にwriteとかって修飾子付けるべきだと思う。
634デフォルトの名無しさん:2006/05/11(木) 02:37:40
>>633
変数なのに・・・
635デフォルトの名無しさん:2006/05/11(木) 02:44:08
const変数
write定数
636デフォルトの名無しさん:2006/05/11(木) 02:45:15
>>633
そして究極的には書き込みという概念が無くなって関数型言語に向かう、と。
637デフォルトの名無しさん:2006/05/11(木) 12:41:14
>>601
のいってることを、自分のあいまいなマシン語の
知識で考えてみた。次の処理アドレスの入った
レジスタがあったような気がするけど、それでも、
終了アドレスから先頭アドレスまで処理するって
のは、そもそもできるんだろうか?知りたい。
638637:2006/05/11(木) 12:43:29
あら、もうおわってたんだ。すんません。
639デフォルトの名無しさん:2006/05/11(木) 16:36:07
>>630
いまどきのPCで動くプログラムならばその程度では速度は大差ないと思うな。
そんなことよりもアルゴリズム見直すとか I/O 関係で非効率な入出力をして
いないかを調べた方がいいと思う。
640デフォルトの名無しさん:2006/05/11(木) 19:25:21
constは定数に使うよりも、

void copy(int*dst,int*src,int n){
int i;
for(i=0;i<n;i++) dst[i]=src[i];
}

この関数のsrc[]をconstで修飾すれば、
dstとsrcのエイリアスがないと思って
ループアンローリングしてくれんじゃね?
641デフォルトの名無しさん:2006/05/11(木) 19:31:43
どうだろうね。memmoveは片側constだけどエイリアスあるし。
642デフォルトの名無しさん:2006/05/11(木) 22:19:45
>>640
それは restrict の仕事。
643デフォルトの名無しさん:2006/05/11(木) 23:35:35
VC8なら __restrict を付ければ・・・・

って思いっきり環境依存でした。スマソ
644デフォルトの名無しさん:2006/05/12(金) 06:25:51
restrictってC99でやっと仕様にはいったんじゃない?
しかも、HPのコンパイラなんかでは最適化上無視してるとか
書かれていたような
645デフォルトの名無しさん:2006/05/12(金) 12:25:57
>>644
>restrictってC99でやっと仕様にはいったんじゃない?
是。
646デフォルトの名無しさん:2006/05/12(金) 22:56:09
constってのは、組み込み系からの派生概念と聞いた覚えがあるけど、そうなんかな?
647デフォルトの名無しさん:2006/05/13(土) 00:21:27
>>646
なんか聞いたことあるな。オブジェクトの配置を ROM にするかどうか
制御する手段が無いと困るから、自然な流れにも感じる。
648デフォルトの名無しさん:2006/05/13(土) 03:38:47
その頃からnoaliasって候補もあったな。

Ritchieの「氏ねや、noalias!」
http://www.quut.com/c/dmr-on-noalias.html
付録に「noalias v.s. restrict」
http://www.lysator.liu.se/c/restrict.html
649デフォルトの名無しさん:2006/05/13(土) 13:59:30
>>647
でも、constなインスタンスもmutableなメンバを持てるでしょう?
その辺...なんか、面倒くさそうだなあ、って思う。
650デフォルトの名無しさん:2006/05/13(土) 15:18:02
しかもコンストラクタ・デストラクタではconstかどうかという区別が存在せず、
constなオブジェクトでもコンストラクタ・デストラクタでは自由にメンバを書き換えられる。
651デフォルトの名無しさん:2006/05/13(土) 17:54:31
>>649-650
そういうのは ROM に置けない。

mutable についてはコンパイラが簡単に判別できるだろうけど、
コンストラクタとデストラクタについては、賢く判別するのは難しい。
現状では、 non-trivial なコンストラクタまたはデストラクタを持つクラスは
ROM に置けないという保守的な判別で済まされると思う。
652デフォルトの名無しさん:2006/05/13(土) 20:25:00
現状ではセクション単位でどれを ROM に置くかってのが簡便でいいんじゃね?
大規模なのは知らんが。ギガビット ROM 程度でやってるうちの会社じゃ問題ないよ
653デフォルトの名無しさん:2006/05/13(土) 21:39:04
ROM上にオブジェクトをコンストラクト(新規作成)するってのは、
何か根本的におかしい気がするんだが
654デフォルトの名無しさん:2006/05/13(土) 21:44:30
>>653
整数いっこをラップした固定小数点数クラスの配列を
ROM に格納したいと考えるのはおかしくないよね?
655デフォルトの名無しさん:2006/05/14(日) 08:56:07
ただ定数式初期化じゃなくて、
コンストラクタ呼び出しのある場合は、
コンパイラ判断難しいよね。>>651
656デフォルトの名無しさん:2006/05/14(日) 09:24:01
>>655
どういう場合を言ってるのかわからない。
657デフォルトの名無しさん:2006/06/02(金) 08:30:44
vectorは通常の配列のように使う限りは
基本的にスピードの点では配列と変わらないと考えて良いのでしょうか?
658デフォルトの名無しさん:2006/06/02(金) 09:25:29
>>657
そういう実装もできるのは確か。
しかしスピードは実測が基本。
659デフォルトの名無しさん:2006/06/09(金) 13:52:03
BCC5.5からVC2005に乗り換えたのですが
VCではループやgotoをインライン展開できるのですか?

BCCでは「for while goto switch 一部のif」は
インライン展開しませんが、VCはやっちゃってくれてるんですかね!?
インライン警告が出ないので本当にインライン化されているか不明なんで聞いてみました。
660デフォルトの名無しさん:2006/06/09(金) 18:15:25
>>659
インライン展開するほうがよいとコンパイラが判断すればインライン展開される。
そこにループだろうと何だろうとがあろうとも。
661デフォルトの名無しさん:2006/06/09(金) 19:48:36
まあじですか!?
神ですな
662デフォルトの名無しさん:2006/06/09(金) 19:56:34
むしろループ如きでインライン展開しなくなるBCC 5.5が古いというだけ。
663デフォルトの名無しさん:2006/06/10(土) 16:42:00
ソート関数書いててさ、基数ソートなんだけど、
static unsigned int aryA[ 1024 ];
void radixSort( unsigned int *src, unsigned int num )
{
  unsigned int aryB[ 1024 ];
  ...
//細かい突っ込み禁止
}
みたいな時にAとBで速度が違うんだけど、
Aが速かったりBが速かったりするんだよね。
スタック領域か、静的領域かの違い(?)だと思うんだけどさ、
要素数は少ないことが分かってるんだけど、
どっちがいいのかねぇ。
個人的にはstaticの方がいいような気がするんだけどさ、
いや、マルチスレッドだと使えないのは分かってるけどさ、
最適化って難しいねぇ。
664デフォルトの名無しさん:2006/06/10(土) 16:51:52
その程度の知識しか無いならそんな最適化は必要ない。
665デフォルトの名無しさん:2006/06/10(土) 17:01:12
すげえマジレス
666デフォルトの名無しさん:2006/06/10(土) 17:03:38
レスがあると思えばただの煽りかよ。
確かに知識はないさ、趣味だし。
でも知識がなくても最適化の必要性とは関係ないしな。
もっと生産的なレスを頼むよ。
667デフォルトの名無しさん:2006/06/10(土) 17:27:28
>>663
つ関数内静的(Static)変数
それはともかく、自分でアセンブリ出力を見比べてみたらどうだ?
668デフォルトの名無しさん:2006/06/10(土) 18:00:43
アセンブリの出力方法がわかりません!><;
669デフォルトの名無しさん:2006/06/10(土) 18:09:31
(664に戻る)
670デフォルトの名無しさん:2006/06/10(土) 18:24:13
その程度の知識しか無いならそんな最適化は必要ない。
671デフォルトの名無しさん:2006/06/10(土) 18:26:23
すげえマジレス
672デフォルトの名無しさん:2006/06/10(土) 19:02:36
レスがあると思えばただの煽りかよ。
確かに知識はないさ、趣味だし。
でも知識がなくても最適化の必要性とは関係ないしな。
もっと生産的なレスを頼むよ。
673デフォルトの名無しさん:2006/06/11(日) 12:50:42
>>666
俺もそんな知識はないが、そんなレスができる奴に惚れた
674デフォルトの名無しさん:2006/06/12(月) 11:59:15
速度に関しては実測するのが基本だろうに
そういう手間を惜しんでる奴が「生産性」とは片腹痛い
675デフォルトの名無しさん:2006/06/12(月) 15:53:49
そういえばおまいら、速度チェックはどうしてますか?
バウンドチェッカ使ってるやつが多いのかね
676デフォルトの名無しさん:2006/06/12(月) 15:57:47
あれはメモリリークだったっけ?
677デフォルトの名無しさん:2006/06/12(月) 16:05:50
素数かどうかを高速で判定する方法を教えてください
678デフォルトの名無しさん:2006/06/12(月) 16:07:39
679デフォルトの名無しさん:2006/06/12(月) 22:25:49
最適化というか、アルゴリズムの問題で、過去にえらい人がいっぱい研究してますよ。
680デフォルトの名無しさん:2006/06/29(木) 00:23:47
C++はPascalなどと比べてコンパイルが遅い。
681デフォルトの名無しさん:2006/06/29(木) 03:28:51
>>680
includeが悪いと思う。importさえあれば。
( Objective-C にはimportがある...と聞いて色めき立ったが、
 偽物だった.... )
682デフォルトの名無しさん:2006/06/29(木) 03:34:40
>>663
どういう条件で、なん%くらいちがうんかな。
ソート対象のデータの並びとか片よりとか、
何によって差が出るのかがはっきりしたら、
事前にデータを走査して、どっちを使うか決めたらいいんじゃなかろうか。
つか、基数ソートか。O(n)の走査も馬鹿にならんな。

aryAを使うようにするんなら、
void radixSort( unsigned int* src, unsigned int num, unsigned int* tmp )
見たく、作業用配列を外部から指定するようにしてもいいかもね。
683デフォルトの名無しさん:2006/06/29(木) 04:09:42
そりゃアドレスがロード時に固定される静的変数と、アクセスするときにスタックポインタ+オフセットを計算する必要がある自動変数で多少の速度差が在るのはあたりまえだろ。
684デフォルトの名無しさん:2006/06/29(木) 06:39:52
>>683
どっちが速いの?
685デフォルトの名無しさん:2006/06/29(木) 08:39:55
>>683
ぶっちゃけアドレスの計算は関係ない。
むしろキャッシュの効きの問題で静的領域とスタック領域を
交互にアクセスしたりすると最悪。
686デフォルトの名無しさん:2006/06/29(木) 10:54:40
>>683
それいつの時代のコンパイラ?
687デフォルトの名無しさん:2006/06/29(木) 11:35:36
CPUじゃなくてコンパイラなんだ
688デフォルトの名無しさん:2006/06/29(木) 11:53:26
>>686
いつの時代だろうと、スタックフレームからのオフセットを
ループ内で何度も計算しなおすコンパイラなどありません。
689デフォルトの名無しさん:2006/06/29(木) 12:21:41
>>688
8080用のCあたりかと
690デフォルトの名無しさん:2006/06/29(木) 13:42:38
>>688
最適化のないコンパイラ、普通にあったよ。
そもそもが自分で色々やるための
算術可能なポインタ, ++/--, registerだったわけだし。
691デフォルトの名無しさん:2006/07/07(金) 13:02:30
そもそも、コンパイルが遅いという話で、
なにかが錯綜してる。。。。。


692デフォルトの名無しさん:2006/07/07(金) 13:04:42
このスレで遅いというと、頭に血が上るということか。w
693デフォルトの名無しさん:2006/08/13(日) 03:24:29
行列のサイズをテンプレート引数で指定する行列クラス作ってたんだけど
部分的特殊化によるループ展開やら
戻り値最適化関数やら用意してやってたんだ。
ところがほとんど効果がないのな。最高でも10%ぐらいしか差がでない。
で、VC8でSSE2オプション指定したら
100倍早くなって腰がぬけそうになった。
ついでに俺がガリガリ最適化したコードと
普通に二重ループするコードの速度差がなくなった(A')
694デフォルトの名無しさん:2006/08/14(月) 03:46:54
ようするに、最近の最適化性能はすごいと?
695デフォルトの名無しさん:2006/08/14(月) 04:59:38
最適になるコードの組み合わせが把握しにくいほど複雑であるという事じゃないの
696デフォルトの名無しさん:2006/08/14(月) 07:29:23
100倍違う?展開したコードをちゃんと見たんかい。
ハードウェアが一緒で変わらないままなのに速度が100倍も
違うなら、最適化で消えていった部分とかあるんだろ。

常識で考えろ。
697デフォルトの名無しさん:2006/08/14(月) 08:59:09
>>696
SSE2の有無が違うだろ。
698デフォルトの名無しさん:2006/08/14(月) 09:07:47
まったくだw
699デフォルトの名無しさん:2006/08/14(月) 09:13:02
非MMX,SSE1,2からSSE2指定で100倍ならありえない話じゃないよな。
でもSSE1からSSE2で100倍はあまりなさそう。ありえなくはないけど。

展開したコードを見たのか?って聞くのは間違ってないが
とりあえず696は今すぐアナルうp
700デフォルトの名無しさん:2006/08/14(月) 09:19:33
倍精度使いまくりならありうるとは思うがな。
701デフォルトの名無しさん:2006/08/14(月) 21:36:48
C++/CLIスレで聞くべきかともおもったのですが
こっちのほうが技術レベルが高そうなので質問をさせてください

一般的にマルチスレッドを使っていると変数がレジスタに
割り当てられにくくなるかと思いますが、GC機構を採用している
C#やJavaなどはある変数を参照している部分がそのローカル関数内に
限定することができないので最適化が発揮しづらくなるのじゃないかと思います

しかしながらC#や最近のJavaは、C++の速度に匹敵するといわれています。
それはどうしてですか?
702デフォルトの名無しさん:2006/08/14(月) 21:40:23
>一般的にマルチスレッドを使っていると変数がレジスタに 
>割り当てられにくくなるかと思いますが
何故?
703デフォルトの名無しさん:2006/08/14(月) 21:49:52
SSE2をONにしたから速度が100倍になるって、例えばどんな場合が
あるんだろう?
FPUを使ってエミュレートすれば100倍も差が付かないと思うんだが。
704デフォルトの名無しさん:2006/08/14(月) 22:11:02
レジスタの本数、モデルの違い、使用するユニットの違い、デコーダの違いetc
705デフォルトの名無しさん:2006/08/14(月) 22:15:04
>>702
マルチスレッドを使っているプログラムだと
同時に2カ所から同じ変数にアクセスされる可能性があるから
必然的に変数をレジスタに割り当てることができない。

ついでにいうとヒープ上にしかインスタンスを確保できない言語の場合は
どうがんばっても微々たる最適化しかできないと思うんだが
俺の認識がちがうのか・・・?
706デフォルトの名無しさん:2006/08/14(月) 22:28:00
いや、スレッド切り替えるときにはレジスタ退避するから。
707デフォルトの名無しさん:2006/08/14(月) 22:30:24
register記憶子を完璧に誤解している奴が現れたか。
708デフォルトの名無しさん:2006/08/14(月) 22:32:36
>>701って結局何が言いたいん?
話の前後はまったく繋がってないわ。1文がやたらと長いわ。
まったく意味が理解できないんだけど。
709701:2006/08/14(月) 23:09:48
いや、勘違いしてないわけだが。
誤解されているようだが、コンテキストスイッチの話をしているわけではないぞ。

最適化してコンパイルすると、メモリ上においておける変数は
極力レジスタに割り付けるようになっていると思うんだが、
それはスタック上に割り当てられた変数にしかできないよな?

C++/CLIのマネージ変数のように、強制的にヒープ上に配置される言語で
なぜC++並の最適化が可能なのか?
って質問かいただけ
710701:2006/08/14(月) 23:10:41

誤 : 最適化してコンパイルすると、メモリ上においておける変数は

正 : 最適化してコンパイルすると、レジスタ上においておける変数は
711デフォルトの名無しさん:2006/08/14(月) 23:21:00
>>701>>709
マルチスレッドでも、関数のローカル変数はスレッド間で共有されないと考えてよいだろう。
となればそれはレジスタに割り当てて問題ない。
残るはグローバル・静的変数だが、こいつらはシングルスレッドでもレジスタに割り当てられることは無いだろう。
また、ヒープ上へ動的に作成するオブジェクトもあるが、これも当然レジスタには割り当てられない。

つまりマルチスレッドだから変数がレジスタに割り当てられにくくなるというのは間違い。

また、JavaもC#もたしかにGCを採用しているが、どちらもint等の基本的な型のオブジェクトに対しては、
(概念上)スタックに割り当てている。最適化でレジスタに割り当てることはC++同様できるはずだ。

Java/C#でヒープ上に割り当てられるのは主にクラス型のオブジェクトということになるが、
クラス型のオブジェクトは大抵レジスタに収まらない大きさになるので、
C++でローカル変数だったとしてもやはりレジスタに載らないことに変わりは無いだろう。

クラス作ってそれを操作するくらいのことなら、C++/Java/C#で表現できることに大差はないので、
最適化に関しては、どれも同じ性能になって当然。JITの手間やヒープからメモリを確保するのがせいぜいのオーバーヘッド。
最近になってJava/C#の最適化技術がC++のそれに追いついてきたという感じかな。
712デフォルトの名無しさん:2006/08/14(月) 23:22:17
>>709
で、その話がマルチスレッドだとレジスタ割付がしにくいという主張と何か関係あるのか?
それは単にHeap AllocationとStack Allocationの違いを話しているようにしか見えんのだが。
713デフォルトの名無しさん:2006/08/14(月) 23:56:11
>>711
void function()
{
static int number=0;
number = ・・・ // いろいろ計算
}
のようにスタティック変数で宣言したものはレジスタに割り当てられないという
ことでしょうか
これがシングルスレッドのコードであることが明示的に指定されて
いればnumberを計算の間はレジスタに割り当てておけると思うのだけれど
現在の最適化はそこまで進んでないってことですね。

マルチスレッドだとレジスタ割り付けがしにくいのでは?という理屈は
このあたりから来てます。

つまりC++とC#/Javaなどの最適化性能に大きな差がない理由というのは
・C#/Javaなどでも基本的な型はスタック上に配置される
・C++でも実際には様々な条件のそろった変数しかレジスタ割り付けされない
・JITの最適化技術の進歩
この3点に尽きるという感じなのかな・・・?
714デフォルトの名無しさん:2006/08/15(火) 00:04:20
GCを採用している言語ではint型などもヒープに配置されるのかと
考えていました。
なので一回変数にアクセスするたびにメモリアクセスが必要になり
C++と比べて速度が遅いはず

と勘違いしておりました。
実際問題ベンチマークテストしてみても大差がないことを確認しているので
不思議に思って質問したわけです。
715デフォルトの名無しさん:2006/08/15(火) 00:06:06
>>714
C#なら、IDEからアセンブリとMSILの混合画面を見れるよ。
最適化してもデバッグにしておけばOK。
716デフォルトの名無しさん:2006/08/15(火) 00:12:17
>>713
そのnumberがfunction内にいる間レジスタに置かれるということは有り得る。
逆にそうさせないためのvolatileというキーワードがあることだし。
そして、それがC++にできてJava/C#にできないわけがない。
717デフォルトの名無しさん:2006/08/15(火) 00:36:45
>>701
> GC機構を採用している
> C#やJavaなどはある変数を参照している部分がそのローカル関数内に
> 限定することができないので最適化が発揮しづらくなるのじゃないかと思います

勝手に思ってろ呆け
718デフォルトの名無しさん:2006/08/15(火) 00:42:04
>>715
.Netは若干まだ勉強中のためそんな機能があるとは知りませんでした。
ありがとうございます。

スレ違いになりそうなのでC#の話題はこれくらいでやめておくとして
>>716
のような話があるから最適化してスレッドを使うときは気をつけなければ
いけないわけですが、C#/Javaではそこまでの最適化は行われていないのか
上記の問題はおきていませんよね
iccなどのちゃんとしたコンパイラを買えばC++でも心配無用なのかな

時間とれるときに自動変数、スタティック変数、グローバル変数などで
違うコードが出力されるのかどうか試してみます。
719デフォルトの名無しさん:2006/08/15(火) 00:44:29
>>717
市ね呆け
720デフォルトの名無しさん:2006/08/15(火) 00:52:18
>>718
馬鹿の考え休むに似たり
721デフォルトの名無しさん:2006/08/15(火) 00:53:29
とりあえず、最近のJIT, HotSpotがどれだけ激しい最適化しているか、
IBMのサイト辺りで勉強して。
722デフォルトの名無しさん:2006/08/15(火) 01:05:36
713のコードでは、最適化でまずくなることを心配することではないだろ。
普通クリティカルセクションか何か排他制御するところだろ。
723デフォルトの名無しさん:2006/08/17(木) 04:58:09
あー、なんというかあきれる。たぶん、自分のことを知識はまだ無いけど賢い
人間だと思ってるんだろうけど、これまでのやりとりを見る限りそれはないか
らもうちょっと態度考えた方がいいと思う。

もし君が国立の学部生なら、周りにこの程度のこと説明できるやつ絶対いるは
ずなんでまずはそのひとに聞いていろいろ教わった方がいいと思う。ネットの
書き込み経由で勉強するには少し頭が悪い気がするので。
724デフォルトの名無しさん:2006/08/21(月) 00:30:03
目くそ鼻くそを笑う
725デフォルトの名無しさん:2006/08/21(月) 01:46:41
大抵、説教はあとで読み返すと恥ずかしいこと書いたなと気づくもんさ
726デフォルトの名無しさん:2006/08/22(火) 21:42:49
>>718
プログラミングは想像や心配じゃなくて言語仕様やら実行環境の仕様や実装を元にして行った方がいいですよ。

マルチスレッド、マルチCPU、マルチコアのプログラムを書くときには、例えば最近のJava ならJSR-133に従う、
アセンブラやC++ の場合はIntelのItanium なら "A Formal Specification of Intel(R) Itanium(R) Processor
Family Memory Ordering"、というようにそのCPUのメモリモデルに従う、
C# (CLR) の場合にはECMA CLI specificationのPartition IのSection 12.6に従う、という風に。
727デフォルトの名無しさん:2006/08/25(金) 00:10:58
コンパイラでできる最適化なんぞ精々2倍がいいとこだし
そもそもクロック単位の話をするのは最後の手段。

ここにいる奴らは当然アルゴリズムを極限まで最適化したうえで
話をしているんだよな?
728デフォルトの名無しさん:2006/08/25(金) 00:53:43
なんかまた頭悪そうなのが湧いてきましたよ。
729デフォルトの名無しさん:2006/08/25(金) 02:06:17
夏ですからね。
730デフォルトの名無しさん:2006/08/25(金) 09:22:05
2倍って何の話だろうな。
ジャンプの漫画じゃあるまいし。
731デフォルトの名無しさん:2006/08/25(金) 10:07:47
ならば俺は3倍界王拳
732デフォルトの名無しさん:2006/08/25(金) 10:43:42
gccでさえ再帰をtail jumpに書き換えるのに…
733デフォルトの名無しさん:2006/08/27(日) 00:43:48
そもそも何を基準に2倍なのか。
734デフォルトの名無しさん:2006/08/27(日) 07:12:41
倍率ドンの更に倍
735デフォルトの名無しさん:2006/09/18(月) 14:34:08
Pentium 4 の上で Visual C++ 7.1 使っているのですが、
同じ計算をする場合、float と double のどちらの型を使うほうが高速でしょうか?
736デフォルトの名無しさん:2006/09/18(月) 14:36:27
>>735
速度は実測が基本。
737デフォルトの名無しさん:2006/09/18(月) 14:43:19
double
738デフォルトの名無しさん:2006/09/18(月) 15:34:52
float
739デフォルトの名無しさん:2006/09/18(月) 15:46:30
とりあえずこういうコードで試してみたら、速度はほとんど同じだった。

__declspec(noinline)
double Func1(void)
{
    double sum = 0;
    for (int i = 0; i < COUNT; i++) {
        sum += sin(sum) + cos(sum);
    }
    return sum;
}

__declspec(noinline)
float Func2(void)
{
    float sum = 0;
    for (int i = 0; i < COUNT; i++) {
        sum += sin(sum) + cos(sum);
    }
    return sum;
}
740デフォルトの名無しさん:2006/09/18(月) 15:54:46
>>739
計算時間の殆どがsin()とcos()に取られそうだが。VC2005なら
sinf()とcosf()を使うと違ってくるんでないかい?
741デフォルトの名無しさん:2006/09/18(月) 16:45:50
>>739
> とりあえずこういうコードで試してみたら、速度はほとんど同じだった。
「どちらも一瞬で終わりました」だったらウケルw
742デフォルトの名無しさん:2006/09/18(月) 16:47:26
このスレは本当に C/C++ の最適化の話をしているのか?

どうせアセンブラ厨が自己満足のために立てたんじゃないか?w
743デフォルトの名無しさん:2006/09/18(月) 17:30:49
>>658
いやvectorは仕様できまってるはずでは。
744デフォルトの名無しさん:2006/09/18(月) 17:32:46
>>743
それはメモリレイアウトが決まっているって話だろ。
メンバ関数やイテレータでどれだけのオーバーヘッドが加わるかは実装依存。
745デフォルトの名無しさん:2006/09/18(月) 18:49:30
一応O記法で条件は定められているけどな。
まぁ、どうせそれで速度が決まるわけではないし。
746デフォルトの名無しさん:2006/09/18(月) 19:29:44
747デフォルトの名無しさん:2006/09/19(火) 11:59:49
>>735
double
748デフォルトの名無しさん:2006/10/07(土) 00:31:02
検索でこのスレひっかかったので蒸し返してみる。
int32_t min9( int32_t a, int32_t b ) {
return b-((b-a)&(-(a<b)));
}

ついでに、min6 のコンパイラがはいたコードみてて思いついたやつ。
int32_t min10( int32_t a, int32_t b ) {
return (&a)[a<b];
}
呼び出し規約依存の上にコンパイラにインライン展開されると死ねる。
ていうか、min6 がインライン展開されるとこいつになるのか、、、
749デフォルトの名無しさん:2006/10/08(日) 15:45:36
その最適化は最適か?
750デフォルトの名無しさん:2006/10/26(木) 16:01:12
doubleとfloatでは演算速度も違いますか?
751デフォルトの名無しさん:2006/10/26(木) 16:07:54
自分でベンチ取って調べろ。

どのみちFPU上ではdoubleだったりそれ以上に変換されるんでどっちでも大差ないとか
最近のCPUだとCPUの演算速度よりメモリのアクセス速度のほうが重要なんで
それなりにでかい配列とかだとメモリ消費量の少ないfloatのほうが有利とか。
752デフォルトの名無しさん:2006/10/26(木) 20:01:18
SSE2使うと、floatだと4演算、doubleだと2演算実行だから、floatの方が速いだろうね。
753デフォルトの名無しさん:2006/11/08(水) 01:31:18
四元ベクトルの正規化をSSEで書いてみたのだけど
D3DXVec4Normalizeのほうが早くてがっかり。
どうなってるんだと逆アセンブリ見たらD3DXのほうは3DNow使ってて、
使ってるCPUごとに命令セット変えてそうな感じだった(ジャンプテーブルをはさんでいる)

アセンブリを比較する限りだと
内積計算するためにfadd使いまくりだった点が決定的に違うのだけど
pfaccに相当する命令ってSSEには無いのかな
754753:2006/11/08(水) 02:19:03
このスレ的には常識なのかもしれないけど
内積で上手い手法は無いのかと探してたらIntelの最適化のpdfに乗ってたので
それいれたらアッサリD3DXより早くなってしまった…
やっぱりメモリオペランドを取り捲ってたのを取り払ったお陰なのかな?
755デフォルトの名無しさん:2006/11/09(木) 21:39:50
そーすきぼんぬ
756デフォルトの名無しさん:2006/11/11(土) 08:08:09
>>755
いや、ほんとたいしたもんじゃないす
擬似コードでアレですがこんな感じ(同意味のVC命令セット使ってます)

float4 dot( float4 v1, float4 v2 )
{
 float4 t = mul(v1,v2);
 float4 s = shuffle( t, t, SHUFFLE(2,3,0,1) ) + t;
 return shuffle( s, s, SHUFFLE(0,1,2,3) ) + s;
}

float4 normal( float4 v )
{
 float4 v2 = dot(v,v);
 return mul( v2, rsqrt(v2) );
}
757デフォルトの名無しさん:2006/11/11(土) 08:11:46
あと内積のほうはIntelのソースのぱくりなんだけど

float4 dot( float4 v1, float4 v2 )
{
 float4 t = mul(v1,v2);
 float4 a = shuffle( t, t, SHUFFLE(2,1,0,3) );
 float4 b = shuffle( t, t, SHUFFLE(1,0,3,2) );
 float4 c = shuffle( t, t, SHUFFLE(0,3,2,1) );
 return t + a + b + c;
}

のほうが命令セットは多くてもペアリングできてるんで高速に動いてたような気はします
ちゃんと時間計っていませんが…
758デフォルトの名無しさん:2006/11/11(土) 08:21:47
これで最後です。最初の遅かった奴はこんな感じ

float4 dot( float4 v1, float4 v2 )
{
 float4 t = mul(v1,v2);
 float s = t.x + t.y + t.z + t.w; // FPUで計算(これはやばかった)
 return float4(s,s,s,s);
}

あと、>>756の方法だと精度が悪くて使い物にならないんで
午後こ〜だのサイトにあるような精度向上をやってるんですけど
それをやった時点で3DNowの手法より遅くなってしまいました
3DNowは精度向上のための専用命令があるからその差がでかいのかな
759デフォルトの名無しさん:2006/11/11(土) 12:24:06
とりあえずループアンローリングとかで
並列度上げないとまだ遅いんじゃないかね
760デフォルトの名無しさん:2006/11/11(土) 13:27:41
ループアンローリングは全然頭に入れてませんでした。
命令セットレベルで入れ替えしてくれるのかな?>MSVC

でも正規化みたいな処理は突然1度だけ現れるみたいな処理がほとんどなので
あんまりそういう最適化を期待してもなぁ…っていう感じではありますが
761デフォルトの名無しさん:2006/11/11(土) 14:44:39
何度も呼ばれないなら最適化なんて不毛…
762デフォルトの名無しさん:2006/11/14(火) 03:07:13
>>761
トータルで見たら何度も呼ばれるけど
その関数が局所的に何度も呼ばれることが無いって話ですよ。
763デフォルトの名無しさん:2006/11/22(水) 04:12:54
ローカル変数の方が最適化されやすいの?
764デフォルトの名無しさん:2006/11/22(水) 04:23:22
うん。
765デフォルトの名無しさん:2006/11/23(木) 09:38:42
ローカル変数は、基本的にはレジスタが割り当てられ、
上手くすればレジスタ間のみの演算で済む。
グローバル変数にすると、必ずメモリ間のやりとりが
はいるので、その転送時間は相当に大きい。

局所的にしか使わない変数がある場合は
適当にブロック作って
ブロック内先頭で変数宣言して使ったりすることもある。
766デフォルトの名無しさん:2006/11/23(木) 12:11:04
> 局所的にしか使わない変数がある場合は
>適当にブロック作って

まあ、最適化にはあんまり関係ないけどな。
767デフォルトの名無しさん:2006/11/23(木) 12:16:55
>>765
> グローバル変数にすると、必ずメモリ間のやりとりが
> はいるので、その転送時間は相当に大きい。

いつのコンパイラやねん。
90年代はじめにはそんなコンパイラ淘汰されたわ。
768デフォルトの名無しさん:2006/11/23(木) 12:20:36
>>766
c++だとデストラクタ呼び出しのタイミングが変わるから
スタック消費量が変わるぞ
とはいえそれくらいか
769デフォルトの名無しさん:2006/11/23(木) 12:22:36
>>768
その場合はオブジェクトへのアクセスがあるんだから
最適化にならないでしょww
770デフォルトの名無しさん:2006/11/23(木) 12:40:56
>>768
関数内のブロックに入ったり出たりするタイミングで、ローカル変数の領域を、
縮めたり延ばしたりするコンパイラって、あんまりないとおもうぞ。
771デフォルトの名無しさん:2006/11/23(木) 13:21:37
>>770
Cの頃から再利用するコンパイラはあるよ。

func1()
{
 {
  A a1;
 }
 {
  A a2;
 }
}

func2()
{
 A a1;
 A a2;
}

func1のほうがスタック消費量は少ない。
スタック消費量が少ない=キャッシュヒット率向上ってことで。
772デフォルトの名無しさん:2006/11/23(木) 13:58:53
具体的に処理系とアセンブリ晒せ
773デフォルトの名無しさん:2006/11/23(木) 14:03:11
vc8, gcc3.4.4(cygwin)
774デフォルトの名無しさん:2006/11/23(木) 14:04:53
>>772
you mean assembler?
775デフォルトの名無しさん:2006/11/23(木) 15:56:44
アセンブラ晒してどうするよ。 gas 使ってますとか、 MASM 使ってますって言ってもねぇ。
776デフォルトの名無しさん:2006/11/23(木) 16:46:18
>>771
gccで簡単なコードを書いて見てみたけど、そんなことはやってなかったなぁ。。。
そういう最適化をする条件って、なにかあるの?
777デフォルトの名無しさん:2006/11/23(木) 17:09:32
簡単なコードを書いてみたら、スタックサイズが小さくなってたよ。
778デフォルトの名無しさん:2006/11/23(木) 17:20:24
ブロックの出入りのタイミングで、スタックを伸び縮みさせるってわけじゃなくて、
領域の再利用ってことか。
まあ、でも、うちの環境で簡単なコードを書いてもぜんぜんかわらなかったな。
ローカル変数がデカかったりしたら、そういう最適化でもするのかね?
779デフォルトの名無しさん:2006/11/23(木) 18:05:39
スタックポインタの計算回数が少いほうが速いよ
780デフォルトの名無しさん:2007/01/06(土) 18:20:57
プログラムがCPUのキャッシュ内に収まっているかどうかはどのようにしたら分かりますか?
VC++はブロック区切ろうと区切るまいと使っても変数のスタックの消費量かわんないよ
関数の先頭でスタックに全部確保しちゃう。

動的オブジェクトのデストラクタの呼び出しのタイミングと変数のスコープだけは変わるだろうけど。
>>780
実行クロック数を計測する。

キャッシュに収まってるか収まってないかでレイテンシの桁が違うはずなのでよくわかると思うけど。
783デフォルトの名無しさん:2007/01/06(土) 18:47:31
>>781
団子ちゃん、どうしてそんなこと知ってんの?
/FAs
785デフォルトの名無しさん:2007/01/06(土) 18:56:15
>>781
変わるよ。
786デフォルトの名無しさん:2007/01/06(土) 18:56:45
>>784
単に、アセンブラの結果を見て、たまたまそーなってたってこと?
それじゃ、必ずしも >>781 のようなことになるとは限らんってことでおk?
ちなみに2003でしか確認してない。
788デフォルトの名無しさん:2007/01/06(土) 19:06:34
さっさとコード晒せよ
789デフォルトの名無しさん:2007/01/06(土) 19:10:28
>>787
2003でも違う結果になる可能性が十分にあると思うんだけど。
790デフォルトの名無しさん:2007/01/06(土) 19:39:37
2003, 2005両方で変わるよ。
791デフォルトの名無しさん:2007/01/06(土) 20:09:23
>>790
>>781 の最後の一行に関しての話なら、C++として当たり前の挙動。
792デフォルトの名無しさん:2007/01/06(土) 21:50:37
>>791
変わるのはスタック消費量。
793デフォルトの名無しさん:2007/01/06(土) 21:54:55
>>792
じゃぁ、団子ちゃんが適当なこと吹いてたってことでFA?
オプション買えてみる


とりあえず配列なんだけど
すまん、どうやっても別々に確保してるんだが。
796デフォルトの名無しさん:2007/01/06(土) 23:16:22
>>795
別々ってどういう意味?
スタックの消費量が実は変わってましたって話?
いや。スタックを再利用してない。
798デフォルトの名無しさん:2007/01/06(土) 23:40:55
cygwinのgccでは再利用するな
vc2005では再利用しない
799デフォルトの名無しさん:2007/01/06(土) 23:40:57
ヒント:>>771の A を、ある程度のサイズの構造体にする
800デフォルトの名無しさん:2007/01/06(土) 23:42:02
gccは再利用しない
g++はする
vc(2003/2005)はc/c++どちらもする

面白い
801デフォルトの名無しさん:2007/01/08(月) 11:53:26
【ネガティブ派遣根性チェック】

3つ以上、思い当たる点があればアナタの性格はひん曲がっており、ネガティブ負け組人生を歩んでいます。

□偽装派遣先の社員の意見にはたとえ間違っていても反対しない
□偽装派遣先から「いつまでもここで仕事してくださいね」と言われるようになりたい
□自社に仕事を持ち帰れるように言われるとムカつく
□自社で仕事なんてできるわけがない
□派遣/受託の差異を指摘する人間はムカつく
□偽装派遣先には仕事だけでなく自分のプライベートについても指示して欲しい
□自分の月額金額を知らない
□偽装派遣先社員より自分の生涯収入が低いのは当然だ
□偽装派遣先に尻尾を振り、いつまでも一緒に仕事をすることが大切だ
□今のプロジェクトが終わっても同じ偽装派遣先に常駐したい
802デフォルトの名無しさん:2007/01/08(月) 12:54:39
Cではauto変数のextentが実はハッキリ定義されていなかったりするんだろうか
C++はデストラクタ呼び出しの順番があるから明示されたけども
803デフォルトの名無しさん:2007/01/08(月) 19:58:00
constをローカルで宣言するより、グローバルで宣言した方が高速なのは仕様ですか?
constならどこで宣言してもプログラム内では単に定数になるだけと思っていたのですが・・・
「定数」にしたいなら static const

自動変数にconstを付ける意味は、コンパイル時に書き換えやろうとしたらエラーや警告を出してくれるだけ。
あとはループの最適化指示とか。
805デフォルトの名無しさん:2007/01/08(月) 21:00:53
コード晒せ
配列でも宣言してるんじゃねーのかw
807デフォルトの名無しさん:2007/01/08(月) 21:58:37
試してみた。

/* stack.c */
#include <stdio.h>
int main(int argc, char **argv) {
  puts(argv[0]);
  {
    int a;
    printf("%p ", &a);
  } {
    float b;
    printf("%p\n", &b);
}
.
> cl
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86

> gcc --version
gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

続く
808デフォルトの名無しさん:2007/01/08(月) 22:00:21
続き

$ gcc stack.c -ostack.gccO0.exe
$ gcc stack.c -O2 -ostack.gccO2.exe
$ gcc -xc++ stack.c -ostack.g++O0.exe
$ gcc -xc++ stack.c -O2 -ostack.g++O2.exe
$ cl /TC stack.c /Festack.clOd.exe
$ cl /TC stack.c /Ox /Festack.clOx.exe
$ cl /TP stack.c /Festack.cl+Od.exe
$ cl /TP stack.c /Ox /Festack.cl+Ox.exe

$ for o in gccO0 gccO2 g++O0 g++O2 clOd clOx cl+Od cl+Ox; do ./stack.$o.exe; done
./stack.gccO0
0x22cce4 0x22cce0
./stack.gccO2
0x22cce4 0x22cce0
./stack.g++O0
0x22cce4 0x22cce0
./stack.g++O2
0x22cce4 0x22cce0
stack.clOd.exe
0012FF6C 0012FF68
stack.clOx.exe
0012FF70 0012FF70
stack.cl+Od.exe
0012FF6C 0012FF68
stack.cl+Ox.exe
0012FF70 0012FF70

VC++2005EEはスタックを再利用する
gccは再利用しない -mno-cygwinもたぶんしない
VCはシンボル数が有る程度多くなると途端に馬鹿になるんだよ
だんごさんは1関数内に変数が200以上あるソースを平気で触ります
810807:2007/01/08(月) 22:24:55
追試

環境は一緒

/* stack2.c */
#include <stdio.h>

#define decl1(x) decl2(0##x) decl2(1##x) decl2(2##x) decl2(3##x) decl2(4##x) decl2(5##x) decl2(6##x) decl2(7##x)
#define decl0(x) decl1(0##x) decl1(1##x) decl1(2##x) decl1(3##x) decl1(4##x) decl1(5##x) decl1(6##x) decl1(7##x)
#define decl2(x) int a##x;
#define use1(x) use2(0##x) use2(1##x) use2(2##x) use2(3##x) use2(4##x) use2(5##x) use2(6##x) use2(7##x)
#define use0(x) use1(0##x) use1(1##x) use1(2##x) use1(3##x) use1(4##x) use1(5##x) use1(6##x) use1(7##x)
#define use2(x) ,&a##x

int main(int argc, char **argv) {
  puts(argv[0]);
  {
    decl0(0);
    printf("%08p %08p %08p %08p %08p %08p %08p %08p\n%08p %08p %08p %08p %08p %08p %08p %08p\n"
      "%08p %08p %08p %08p %08p %08p %08p %08p\n%08p %08p %08p %08p %08p %08p %08p %08p\n"
      "%08p %08p %08p %08p %08p %08p %08p %08p\n%08p %08p %08p %08p %08p %08p %08p %08p\n"
      "%08p %08p %08p %08p %08p %08p %08p %08p\n%08p %08p %08p %08p %08p %08p %08p %08p\n" use0(0));
  }

続く
811807:2007/01/08(月) 22:26:43
続き

  puts("");
  {
    decl0(1);
    printf("%08p %08p %08p %08p %08p %08p %08p %08p\n%08p %08p %08p %08p %08p %08p %08p %08p\n"
      "%08p %08p %08p %08p %08p %08p %08p %08p\n%08p %08p %08p %08p %08p %08p %08p %08p\n"
      "%08p %08p %08p %08p %08p %08p %08p %08p\n%08p %08p %08p %08p %08p %08p %08p %08p\n"
      "%08p %08p %08p %08p %08p %08p %08p %08p\n%08p %08p %08p %08p %08p %08p %08p %08p\n" use0(1));
  }
}

$ cl /Ox stack2.c /Festack2.clOx.exe 
$ gcc -O2 stack.c -ostack2.gccO2.exe

まだ続く
812807:2007/01/08(月) 22:27:33
まだ続き

$ ./stack2.clOx.exe
stack2.clOx.exe
0012FF70 0012FF68 0012FF60 0012FF58 0012FF50 0012FF48 0012FF40 0012FF38
0012FF30 0012FF28 0012FF20 0012FF18 0012FF10 0012FF08 0012FF00 0012FEF8
0012FEF0 0012FEE8 0012FEE0 0012FED8 0012FED0 0012FEC8 0012FEC0 0012FEB8
0012FEB0 0012FEA8 0012FEA0 0012FE98 0012FE90 0012FE88 0012FE80 0012FE78
0012FE74 0012FF6C 0012FEEC 0012FF2C 0012FEE4 0012FF4C 0012FEDC 0012FF24
0012FED4 0012FF5C 0012FECC 0012FF1C 0012FEC4 0012FF44 0012FEBC 0012FF14
0012FEB4 0012FF64 0012FEAC 0012FF0C 0012FEA4 0012FF3C 0012FE9C 0012FF04
0012FE94 0012FF54 0012FE8C 0012FEFC 0012FE84 0012FF34 0012FE7C 0012FEF4

0012FEF4 0012FE7C 0012FF34 0012FE84 0012FEFC 0012FE8C 0012FF54 0012FE94
0012FF04 0012FE9C 0012FF3C 0012FEA4 0012FF0C 0012FEAC 0012FF64 0012FEB4
0012FF14 0012FEBC 0012FF44 0012FEC4 0012FF1C 0012FECC 0012FF5C 0012FED4
0012FF24 0012FEDC 0012FF4C 0012FEE4 0012FF2C 0012FEEC 0012FF6C 0012FE74
0012FE78 0012FE80 0012FE88 0012FE90 0012FE98 0012FEA0 0012FEA8 0012FEB0
0012FEB8 0012FEC0 0012FEC8 0012FED0 0012FED8 0012FEE0 0012FEE8 0012FEF0
0012FEF8 0012FF00 0012FF08 0012FF10 0012FF18 0012FF20 0012FF28 0012FF30
0012FF38 0012FF40 0012FF48 0012FF50 0012FF58 0012FF60 0012FF68 0012FF70

さらに続く
813807:2007/01/08(月) 22:29:07
$ ./stack2.gccO2.exe
./stack2.gccO2
0x22cbe8 0x22cbec 0x22cbf0 0x22cbf4 0x22cbf8 0x22cbfc 0x22cc00 0x22cc04
0x22cc08 0x22cc0c 0x22cc10 0x22cc14 0x22cc18 0x22cc1c 0x22cc20 0x22cc24
0x22cc28 0x22cc2c 0x22cc30 0x22cc34 0x22cc38 0x22cc3c 0x22cc40 0x22cc44
0x22cc48 0x22cc4c 0x22cc50 0x22cc54 0x22cc58 0x22cc5c 0x22cc60 0x22cc64
0x22cc68 0x22cc6c 0x22cc70 0x22cc74 0x22cc78 0x22cc7c 0x22cc80 0x22cc84
0x22cc88 0x22cc8c 0x22cc90 0x22cc94 0x22cc98 0x22cc9c 0x22cca0 0x22cca4
0x22cca8 0x22ccac 0x22ccb0 0x22ccb4 0x22ccb8 0x22ccbc 0x22ccc0 0x22ccc4
0x22ccc8 0x22cccc 0x22ccd0 0x22ccd4 0x22ccd8 0x22ccdc 0x22cce0 0x22cce4

0x22cae8 0x22caec 0x22caf0 0x22caf4 0x22caf8 0x22cafc 0x22cb00 0x22cb04
0x22cb08 0x22cb0c 0x22cb10 0x22cb14 0x22cb18 0x22cb1c 0x22cb20 0x22cb24
0x22cb28 0x22cb2c 0x22cb30 0x22cb34 0x22cb38 0x22cb3c 0x22cb40 0x22cb44
0x22cb48 0x22cb4c 0x22cb50 0x22cb54 0x22cb58 0x22cb5c 0x22cb60 0x22cb64
0x22cb68 0x22cb6c 0x22cb70 0x22cb74 0x22cb78 0x22cb7c 0x22cb80 0x22cb84
0x22cb88 0x22cb8c 0x22cb90 0x22cb94 0x22cb98 0x22cb9c 0x22cba0 0x22cba4
0x22cba8 0x22cbac 0x22cbb0 0x22cbb4 0x22cbb8 0x22cbbc 0x22cbc0 0x22cbc4
0x22cbc8 0x22cbcc 0x22cbd0 0x22cbd4 0x22cbd8 0x22cbdc 0x22cbe0 0x22cbe4

おしまい

やっぱりVC++2005EEは再利用する、gccは再利用しない
// いや、こんな極端な例はないと思うけどさ。
// それよりもVC++で順番が入れ替わってるのが気になる
2005もANSI APIが遅くなきゃさっさと乗り換えるんだが
815デフォルトの名無しさん:2007/01/08(月) 22:41:36
>>814
遅いってのはマルチスレッド用ライブラリしかないってこと?
なんでANSIだけ遅いの?UNICODEとどう違う?
とにかく文字列関連のAPIが絶望的に遅い。
UNICODEに変換して処理するからっぽいけど、2003まではそんなことはなかった。

逆にUNICODE API利用時のパフォーマンスは上がってるっぽいのでまあ察しの通りでしょう
817デフォルトの名無しさん:2007/01/08(月) 22:57:13
>>816
????よくわからん
msvcr80.libのnarrow charの関数が内部でUNICODEに変換して〜W()を呼び出すってこと?
それなら/MDでmsvcrt.dllにリンクすれば今までと変わらないよねぇ

出来れば簡単なベンチとテストソースキボン
818デフォルトの名無しさん:2007/01/09(火) 01:02:28
ダンゴのいいかんげんさに笑った
あんまり信用できんな
819デフォルトの名無しさん:2007/01/09(火) 01:03:29
あんまり、どころじゃねえよ
俺は最初からあぼーん登録してる
これでいくわ
821デフォルトの名無しさん:2007/01/09(火) 01:15:06
>>820
じゃぁ、今度から団子ちゃんじゃなくてケンチャンって呼ぶね♪
822デフォルトの名無しさん:2007/01/09(火) 06:42:52
トリップを考慮しない辺りが……
モツ煮タンとの共有トリだけど
824デフォルトの名無しさん:2007/01/10(水) 20:37:26
>>団子
ANSI関数が遅いのは結局妄想?
825デフォルトの名無しさん:2007/01/10(水) 23:23:25
>>団子
VCがスタック再利用しないってのは結局捏造?
>>824
http://d.hatena.ne.jp/NyaRuRu/20060227/p1

>>825
具体的にはhttp://www.darkside.com.au/bitslice/
のdesevalをforceinlineで全部変数展開して実行してる。
少なくともVC2003では超がつく糞コード吐く
↑の場合ANSIってよりはMBCSかも
828デフォルトの名無しさん:2007/01/11(木) 20:32:27
forceinline(笑)
829デフォルトの名無しさん:2007/01/12(金) 23:12:01
> forceinlineで全部変数展開
> 超がつく糞コード吐く

かわいそう
830デフォルトの名無しさん:2007/01/14(日) 09:23:37
お前初めてかここは?
831デフォルトの名無しさん:2007/01/14(日) 12:22:25
>>826
std::basic_string<TCHAR>で追試してみた。

CString::Formatの代わりにstd::basic_stringstream<TCHAR>::operator <<を使った場合(3000回ループ)
narrow
 add: 2179, search: 11674
MBCS
 add: 2365, search: 11947
UNICODE
 add: 5894, search: 32096

std::snprintf/std::snwprintfを使った場合(150000回ループ)
narrow
 add: 764, search: 1614
MBCS
 add: 775, search: 1622
UNICODE
 add: 1558, search: 2822

cl.exe ver14.00.50727.42 for 80x86
/O2 /GL /FD /EHsc /MT /GS- /TP

# いやー、sstream遅いねー、実測するとよくわかるや
# UNICODEはバイト長が単純に倍になるからその分不利なんだろーな
# ATLは使わないから知らん
832デフォルトの名無しさん:2007/01/14(日) 12:37:46
そりゃsstreamの使い方がド下手なだけだな。
cppllあたりの過去ログでも嫁。
833デフォルトの名無しさん:2007/01/14(日) 12:56:07
>>832
下手でスマソ、cppllは最近登録したばっかだ
でもさ、operator <<(sstream &, int)に使い方も糞もあるの?
intから文字列へ変換する移植性のある方法ってsnprintfかoperator <<かboost::lexical_castくらいしかないよね?
それともresize()しとけってだけの話?

さらに追試
cl.exe ver13.10.3077 for 80x86
/O2 /FD /EHsc /M{L,T} /TP

/ML{add,search}, /MT{add,search}の順に
sstream
narrow
 4420, 24104, 4382, 24183
MBCS
 4286, 23185, 4415, 24319
UNICODE
 6412, 32975, 6434, 35718

sprintf
narrow
 997, 2021, 1001, 2038
MBCS
 930, 1956, 1012, 2067
UNICODE
 1413, 2628, 1761, 3735

# むしろこっちのほうが相対的にMBCS遅いんですが。
# sstreamだと特にひどい。しかも全体的に遅いし。
834デフォルトの名無しさん:2007/01/14(日) 22:55:45
もうCでパフォーマンスうめぇwwwっていう時代は終わったんだよなぁって感じがする
835デフォルトの名無しさん:2007/01/22(月) 23:23:33
55 名前: デフォルトの名無しさん [sage] 投稿日: 2007/01/22(月) 22:51:26
>>53
1の開発環境はWindowsだと思うのでx86。
スタックポインタの場合、[esp-8]などと一発でアクセスできるが、
そうでない場合[eax]とアクセスする前にeaxにポインタを格納する手間が要る。
もしくは、eaxをポインタに占有されて使えるレジスタが減ってしまう。

60 名前: デフォルトの名無しさん [sage] 投稿日: 2007/01/22(月) 23:08:00
>>55
例えば mov edx,[MemAddress] と言う形式の指定方法があるので、
わざわざアドレスをレジスタにロードする必要は無い。


俺は55だが、なるほど、MemAddressは即値なのね。
あらかじめアドレスはわかってるようにできるものなの?
836デフォルトの名無しさん:2007/01/22(月) 23:42:58
データの位置の決定、アドレスの数値決定はリンカの役目。

命令が相対アドレス指定なら、リンカはそのまま値を確定してしまうし、
絶対アドレス指定命令の場合は、普通は実行形式にアドレス再配置
情報が記録されて、実行前にOSが絶対アドレスを全部補正するはず。
837デフォルトの名無しさん:2007/01/22(月) 23:59:12
>>836
アドレス再配置とかすごいな。
俺の方が勉強不足だったようだ。

質問になってしまうが、グローバル変数のアドレスを決めてしまって
mov edx,[MemAddress]式のアクセスで高速化というのは、あり?
838デフォルトの名無しさん:2007/01/23(火) 00:08:10
C++のようにライブラリが重い言語が盛んに使われるように
なったので、重くなったソフトを軽々と動かすためにCPUの
高速化が必要になった希ガスw
839デフォルトの名無しさん:2007/01/23(火) 00:26:40
>>837
それはレジスタに置いておく代わりに mov edx,[MemAddress] という事?

メモリから読む場合は、データをとってくるのに時間がかかったり制限も色々あるので、
出来る限りレジスタに残しておいたほうがいいと思う。

mov edx,[ebp-8]とどっちがいいかという話なら、実行コストはちょっと分からない。
詳しい実行コストが知りたいのなら↓のスレあたりが詳しいのでおすすめ。

x86命令の所要クロック計測スレPart3
http://pc10.2ch.net/test/read.cgi/tech/1168399966/
840デフォルトの名無しさん:2007/01/23(火) 00:28:41
>>837
あり、というより大抵のコンパイラ・リンカはそうしていると思う。
841デフォルトの名無しさん:2007/01/23(火) 00:49:02
>>839
いや、おいらはグローバル変数のアドレスは決まってないと思っていたので、
数字を決めておくのと決めないのと、どちらがいいのかと思って。
>>840ということなので、決めた方がいいようですね。
おいらはそのスレの住人なので、まず周辺を勉強し直してから測定してみまつw

>>839>>840ありがとうございました。
>>841
決まってる。
ただしプロセスローカルな仮想アドレスでの話だけど。
IA-32ではアドレス空間は仮想化されてて別々のプロセスでも同じアドレス値を持てる。
ただし他のプロセスのメモリ空間へは普通の方法では直接アクセスできない。

マルチスレッド化とか考えるなら、なるべく使わず自動変数とか、構造体を
アドレス渡しして操作したほうがいい。
多少命令長が増えるが[ecx+OffsetAddress] みたいな相対アドレス指定のほうが
何かと便利。

セットしたい値が決まってるなら即値使った方がいい。
これは特に意識しなくとも最適化でそうなるが。
なによりグローバル変数はバグの根源。定数ならまだいいが。
843デフォルトの名無しさん:2007/01/23(火) 07:27:26
>>841
ちょっと整理しておこうか。
・ローカル変数はスタックに置かずにレジスタに置くかも知れない。
・グローバル変数は(必要となる範囲の先頭で)レジスタに保持してしまうかもしれない。
#一般的に最適化は関数単位だから、関数脱出までには書き戻すはずだが。
従って、グローバル変数だから速いとか遅いとか、一概には言えない。

また、関数への引き渡しに際しても、インライン展開できるコンパイラでは
呼び出し元のローカル変数をレジスタにキープしたまま呼び出し先で参照するかもしれない。
この点でも、グローバル変数の方が速いとは言えなくなる。
844デフォルトの名無しさん:2007/01/23(火) 12:01:11
ローカル変数はスタックにおかれるから、
キャッシュヒット率が高いことが期待できるよ。
もはやこっちのほうが重要。

あと命令長は考えても無駄。
845デフォルトの名無しさん:2007/04/05(木) 08:58:10
長いパイプラインを持つCPUを使い場合、プログラムでどうしても分岐(if文)を
書かなければならない場合、最初に持ってきた方がよいのですか?
それとも最後に持ってきた方がよいのでしょうか?
846デフォルトの名無しさん:2007/04/05(木) 09:41:47
試して貼ってくれ。
847デフォルトの名無しさん:2007/04/06(金) 09:01:45
400m位?
848デフォルトの名無しさん:2007/04/06(金) 09:19:48
極東から1マソ`くらいあるでしょ?
849デフォルトの名無しさん:2007/04/06(金) 10:09:06
これはダンゴ先生を呼ぶしかない。
850デフォルトの名無しさん:2007/04/06(金) 21:26:51
>>845
IntelのCPUならこれを読め

IA-32 インテル(R) アーキテクチャー最適化リファレンス・マニュアル
http://download.intel.com/jp/developer/jpdoc/IA32_Final_i.pdf
2-14 静的予測
851デフォルトの名無しさん:2007/04/06(金) 21:27:31
ダンゴを召喚するな
って言うと来てくれるよ
852`∀´>っ-○◎●:2007/04/06(金) 21:42:24
ホロン部です
853デフォルトの名無しさん:2007/04/06(金) 23:32:04
むっ、明日の早朝に、下半身に性的予測あり。
854デフォルトの名無しさん:2007/04/07(土) 08:22:55
a=a+1よりa++の方が速いと言いますが、a=a+1のようなコードに出会ったときに、自動的にa++に変換して最適化してくれるような
賢いコンパイラは何故無いのでしょうか?
855`∀´>っ-○◎●:2007/04/07(土) 08:26:37
> a=a+1よりa++の方が速いと言いますが

どこのロートルがそんなこと言ったのよ
そんなんでコードの効率が変わるようなコンパイラなんていまどき有りません
856デフォルトの名無しさん:2007/04/07(土) 09:05:33
>>854
逆に寧ろ、a = a + 1とa++で違うコードを吐くコンパイラをご存知なら教えてください。

って言ってやれ。
857デフォルトの名無しさん:2007/04/07(土) 14:29:03
しかもネトバの場合 inc より add の方が速いし。
858`∀´>っ-○◎●:2007/04/07(土) 14:45:42
アレだろ。頻繁に使う変数にはregister宣言した方が速いとかいうロートルだろ。
実際は最適化を阻害するんだが。
859デフォルトの名無しさん:2007/04/07(土) 14:46:04
>>854
a++より++aの方が速い。
賢いコンパイラなら変わらないかもしれないが。
860デフォルトの名無しさん:2007/04/07(土) 14:58:06
>>859
組み込み型に限って言うなら、
a++; と ++a; で違うコード吐くコンパイラ知らない。
b = a++; と b = ++a; なら違うだろうけど。
861デフォルトの名無しさん:2007/04/07(土) 15:15:44
aの型に関してなにも想定せずに速いとか遅いとか言ってもナ。
862`∀´>っ-○◎●:2007/04/07(土) 15:20:57
なるほど、++と+=演算子に別の関数がオーバーロードされてるクラスのインスタンスなのか


ねーよwwwwwww
863デフォルトの名無しさん:2007/04/07(土) 16:36:01
++ -> マジックインクリメント
+= -> 文字列の結合
だったとしたらどうするつもりだ。
864デフォルトの名無しさん:2007/04/07(土) 17:05:39
組み込み型に関しても、a++が++aより速くなる可能性は0だから
前置でいいところは前置で書くべきだな。
ループはwhile(a++ < b)よりもwhile(++a <= b)にすべきだな。
865`∀´>っ-○◎●:2007/04/07(土) 18:48:20
ループはdo-whileだよな
866デフォルトの名無しさん:2007/04/08(日) 02:29:28
でも、最近、コンパイラ毎の最適化評価情報ってあまり聞かないな。
867`∀´>っ-○◎●:2007/04/08(日) 09:52:11
SPU-GCCが意味不明なコード吐きまくるから困る
868デフォルトの名無しさん:2007/04/08(日) 22:41:28
自分で直しちゃえ
869デフォルトの名無しさん:2007/04/08(日) 22:49:20
無理だってばw
870デフォルトの名無しさん:2007/04/09(月) 00:44:12
rtx の頃はやらないと使い物にならなかったからやったけど
今のは複雑らしいから大変だろうねぇ
871デフォルトの名無しさん:2007/04/09(月) 11:11:42
>>864
>a++が++aより速くなる可能性は0だから
それが式中ではなく単体で使われてれば、
a++が++aより遅くなる可能性も殆どないですが。
872デフォルトの名無しさん:2007/04/09(月) 15:16:02
>>871
可読性を落とさずに速くなる可能性があるんだから、a++を使う意味もないだろう。
ユーザ定義型だと最適化も期待できないし、前置++を使う癖を付けておくことは
悪くないと思うけどな。
873デフォルトの名無しさん:2007/04/09(月) 21:38:19
バリバリC++のoperator使いだからa++の非効率さは知ってるんだが、a++の方が好きだなあ。
inc(a)よりa.inc()の方が分りやすいと思うのは日本人の性?
874デフォルトの名無しさん:2007/04/09(月) 21:57:19
後置はむしろ使える場面でも使わないな。紛らわしいから。
875デフォルトの名無しさん:2007/04/09(月) 22:15:28
>>873
そういう合目的的でない直感を排していけない人は、
プログラマに向いてないと思う。いつか必ず落とし穴になる。
876`∀´>っ-○◎●:2007/04/09(月) 23:39:33
Rubyで++をうっかり使ってパーズエラー
877873:2007/04/10(火) 00:28:30
もうここまで来ると子供のだだだが、SIMDとかで
A(B(C(D(E(f), g, h)), k))
とかなってると括弧の対応がエディタの機能に頼らないと分らなくね?
対応している括弧が分っても引数が何処の関数に所属しているか戸惑う。

実際の解決はだらだら全部の処理の行を分けて記述する事になるんだが、
f.E().D(g, h).C().B(k).A()
という表記が出来た方がいくらかマシだなあと。
あくまで例だからな。本当にそんな実装するくらいならx86のfvecみたいに演算子作る。
878873:2007/04/10(火) 00:39:03
a++と何の関係があるんだって話だが、つまりa++と++aはa.inc()、inc(a)の関係にあって、a++とかa.inc()が使えるならそっち使っちゃうなという俺の腐れ脳内の紹介。

でもa.inc()がaを1だけインクリメントしてくれるとした場合
a++ + bとa.inc() + bは結果が異なるから本当にだだだな。
どうみても妄想です、本当に(ry
879デフォルトの名無しさん:2007/04/10(火) 00:42:13
a++と++aの違いと
inc(a)とa.inc()の違いって
全然違うところに無いか?
880879:2007/04/10(火) 00:42:59
878読んでなかった
スマソ
881`∀´>っ-○◎●:2007/04/10(火) 00:44:48
SSE*でDQWORDのアクセスするとさ

__m128i tmp = _mm_load_si128( &a[i] );

とかやるじゃん

a => eax
i => edx

とするとx86のアドレッシングモードに、「16倍」って無いから、

shr edx, 4
movdqa xmm0, [eax + edx]

とかいちいちやんないといけないのよね。
だから、添字じゃなくてポインタとかをバイト数のオフセット値として持ったほうが効率いいんだけど

_mm_load_si128( (__m128i)(((char*)a) + offset) );

てらめんどくさす('A`)
882デフォルトの名無しさん:2007/04/10(火) 01:05:16
>>877
C++なら適当なメンバ関数でreturn *this;しとけば大体希望通りの記述が出来るんじゃないか。
intrinsics+inlineならパフォーマンス上のペナルティもないし。
883デフォルトの名無しさん:2007/04/10(火) 03:09:04
"パーズエラー" の検索結果 約 40 件中 1 - 10 件目 (0.21 秒)
"パースエラー" の検索結果 約 35,100 件中 1 - 10 件目 (0.14 秒)
884デフォルトの名無しさん:2007/04/10(火) 08:37:08
>>883
辞書引くとどっちの発音でもいいみたいだが...
885デフォルトの名無しさん:2007/04/10(火) 09:18:51
ニューヨークヤンキーズ
カーネルサンダーズ
886デフォルトの名無しさん:2007/04/10(火) 09:21:42
スティーヴ・ジョブズ


ただ慣用から外れた表記で己を誇示するのはどうかと
それが団子クオリテイか
887デフォルトの名無しさん:2007/04/10(火) 10:44:03
タイガーズ
888`∀´>っ-○◎●:2007/04/10(火) 21:53:37
ティガー
889デフォルトの名無しさん:2007/04/11(水) 13:01:48
だんこ
890デフォルトの名無しさん:2007/04/11(水) 17:51:00
`∀´
エラない状態で指定してもあぼーん出来ません。

レスはたとえばhttp://pc11.2ch.net/test/read.cgi/tech/1084676298/888とか
891デフォルトの名無しさん:2007/04/11(水) 17:52:17
ごめんなさい間違えました
892( ・〜・)−◎○−m:2007/04/11(水) 18:07:04
全体何がしたいのかと。
893デフォルトの名無しさん:2007/04/12(木) 03:44:26
俺はある方法で確実にあぼーんしてる
書くと対策しやがるから書かないでおくが・・
894デフォルトの名無しさん:2007/04/12(木) 13:16:57
最近のコンパイラはSSEなどは、自動的に使用してくれるようなのですが、
SSEに優しい、コードの書き方とかってどこかに解説されていませんか?
895デフォルトの名無しさん:2007/04/12(木) 13:25:40
インテルの技術資料pdfにあった気がするけど
どれだったか思い出せない
896デフォルトの名無しさん:2007/04/12(木) 18:14:38
897デフォルトの名無しさん:2007/04/12(木) 18:36:09
Array-of-Structures(AoS)ではなくStructure-of-Arrays(SoA)を使えってのが定番だね。
ttp://download.intel.com/jp/developer/jpdoc/apps_simd_j.pdf
898デフォルトの名無しさん:2007/04/12(木) 20:35:04
コードの見た目AoSだがメモリはSoAに配置にするような
変態c++テンプレート希望
899デフォルトの名無しさん:2007/04/13(金) 06:42:08
オブジェクト指向に従えば、オブジェクトがいくつ、例えば
CClass a[100];
の様なやり方が、自然ですが、SoAとOOPをうまく融合する方法はないでしょうか?
900デフォルトの名無しさん:2007/04/13(金) 09:43:33
SoAなコンテナクラスを作ればいいんだろうけどね。
オブジェクト指向的には、複数のオブジェクトの集まったオブジェクトとして扱うとか。
901デフォルトの名無しさん:2007/04/13(金) 09:50:59
つまり、リンゴが1つ2つではなくリンゴ袋レベルから物事をとらえろと?
902デフォルトの名無しさん:2007/04/13(金) 09:54:26
そそ、そういうコンテナクラスがあればってことになってとどのつまりは>898w
903デフォルトの名無しさん:2007/04/13(金) 14:56:31
SIMD最適化が必要になるクラスってかなり限定されないか。
ほとんどの演算をSIMDで行わないと
mmx(xmm)←→汎用レジスタの変換に時間取られるから、
データの並びをSoAにするだけじゃダメなわけだし。
904( ・〜・)−◎○−m:2007/04/13(金) 16:22:17
そうでもない。
905デフォルトの名無しさん:2007/04/14(土) 00:26:23
そうなの・・・?
でも、pextrwとかばっかり使ってるとやっぱおそいっしょ。

普通のクラスってintとかbyteとかを混在して持ってるから、
クラスの並びを CClass[250][4] (>>899から) とかにするだけじゃうまくいかないと思うんだよな。
SoAで大切なのは、SIMDで素直に扱える型を実現することだから、
結局CClass側でも、float[4]やdouble[4]を持つ、もしくはfloatやbyteのみ持つ
とかの工夫をしないといけないだしょ?
そうすると、なんというか、
CClassのもつデータによってClass[500][2]とかClass[125][8]とか分割の仕方を変えないといけないし、
どんなクラスでも適切にSoA型に並べる汎用コンテナクラスを作るのはちょっと難しいと思う。
あと、与えられるクラスの条件もかなり厳しくなるはず。
(もてるデータはPODのみとか、vtableが必要になる継承は禁止とか……)

結局、SIMDで演算させるためには設計の段階からデータ配置を意識しないといけない。
そう考えるとfvec.hやdvec.hにあるクラスを最初から使うのが
手軽で分かりやすいということになると思うんだよな。
906デフォルトの名無しさん:2007/04/14(土) 00:38:35
うおっ。何が言いたいのかよく分からんな……

とりあえず、汎用コンテナクラスを作るくらいなら、
必要になってからドメイン スペシフィック(?)にコンテナ作った方が
多分分かりやすいし間違いなく速度は出ますよ、
と言いたかった。
907`∀´>っ-○◎●:2007/04/14(土) 02:49:41
>>903
AMDだけじゃねそれ
Vectorパスでデコードするから使う度にストールする。

つーか、pextrwはロード・ストアユニットを使わないから良いのです。
Core2ならpextrwはレイテンシ3-スループット1でアクセスできるから
ちょっとしたローカルストア代わりに使える。
MM/XMMレジスタで計96個のWORD値を保持できるwww
(ちなみにpinsrwはCore 2でも遅い)
ロード・ストアって一番利用頻度高いから、1回の操作で
8個のWORD値を読み書きできる意味は大きい。



と、たまにモグリのソフト屋の集まりでそういうネタがよく出るんだが
実用性には疑問符が。
つか、ここ、うちのオフの参加者いる悪寒
(団子の中の人ってことは知られてない筈だけど)
908デフォルトの名無しさん:2007/04/14(土) 13:36:06
Pentium4ではpinsrwが4-1、pextrwが7-2だったし、
AMDでpextrw使ったらえらい遅くなったから、
この命令はずっと避けてたんだが・・・
実際はそうでもないのね。

mm/xmmレジスタをローカルストア代わりに使えたら嬉しいなぁ。
pinsrwとpextrwの性能がいいCPUならかなり使えそう。

ただ、遅い石のことも考慮するとそう簡単にはいかないか……
ってか、ほんとにAthlonXPでの遅さは異常。
AMD系だとたしか op reg [mem] 系の命令が推奨されていて、
L1のレイテンシ-スループットが大抵3-1くらいだと考えると、
素直にスタック使った方が速そうではある。
(いや、たしかにロードストアユニットは使うけどさ^^)

AMDマンセーな自分としては避けたい気分なんだけど、
Intel系でpinsrwやpextrwが速い石ならかなり可能性はありそうだと思った。
当然、要プロファイルだけど^^
とりあえず、レジスタでLSな発想自体は面白いと思う。

あと自分はオフの参加者ではないよ。
そういうのに参加したことは一度もない;;
909デフォルトの名無しさん:2007/04/14(土) 13:44:15
908の補足;
VectorPathについての理解が甘かった。
ちょっとピントをはずしてるぽ。
勉強してきます。
910デフォルトの名無しさん:2007/04/14(土) 14:44:29
「うちのオフ」がどんなものかにもよるけど、団子クラスの知識が集まっているなら覗いてみたい。
911デフォルトの名無しさん:2007/04/14(土) 15:13:44
> 団子クラスの知識が集まっているなら覗いてみたい

めちゃくちゃ厨くせえ。だって所詮団子レベルだろ?
願わくばその団子クラスのオタモダチがム板になだれ込んで来ないことを希望。
912デフォルトの名無しさん:2007/04/14(土) 16:11:24
団子レベルで理解してるほどのハッカーはあまりいないし、なにげに貴重だと思う。
913デフォルトの名無しさん:2007/04/14(土) 16:29:00
付き合いたいともお知り合いになりたいとも書いてないからな。
厨くさい会話の中に、どれだけ利用できる情報があるやらw
#あると思うのが>910だろうし、ないと思うのが>911なんだろうね。
914デフォルトの名無しさん:2007/04/14(土) 18:37:48
インテルコンパイラにおけるPGOの手順てどこに載っているのでしょうか?
Webページでも良いので教えてください。
915デフォルトの名無しさん:2007/04/14(土) 20:13:30
>>913
まぁ910と911よりは「うちのオフ」の面々のほうが有用な雰囲気。
916デフォルトの名無しさん:2007/04/14(土) 20:27:09
面々に糞団子を含める?
917デフォルトの名無しさん:2007/04/14(土) 20:30:59
>>914
日本の販売元であるエクセルに問い合わせたら?
918デフォルトの名無しさん:2007/04/14(土) 20:46:16
Opteronの最適化に関する日本語の資料ってありませんか?
919デフォルトの名無しさん:2007/04/14(土) 20:52:48
>>918
なさげ。
C/C++だったら、まっとうなコード書いてれば普通に速い。
特別に速くしたいのだったら、英語版の最適化ガイドをいっしょうけんめい
読んでちょうだい。実際にはあまり役に立たないけど。

具体的に困ってるコード例を貼ったら添削してもらえるとオモ。
920`∀´>っ-○◎●:2007/04/15(日) 04:14:25
>>914
エクセルソフトのサイトからPDF落とせるはずだけど?
921デフォルトの名無しさん:2007/04/15(日) 13:13:11
gccでコンパイルすると、例えばx/10.0はコンパイル時にx*0.1に置き換えられてしまいますが、
これをしないように指示する方法はないでしょうか?O0だとすべての最適化がきかなくなってしまうので
この置き換えだけを抑制したいのですが。
922`∀´>っ-○◎●:2007/04/15(日) 13:17:09
しないようにしたい理由って何?


{
  volatile double tmp = x;
  tmp /= 10;
}
923`∀´>っ-○◎●:2007/04/15(日) 13:19:57
↑は確かめてないわ。たぶんこれなら確実におk

volatile double Ten = 10.0;

x/Ten
924デフォルトの名無しさん:2007/04/15(日) 13:45:52
>>921
no fast math とか、そんなん無かったか?
925デフォルトの名無しさん:2007/04/15(日) 14:19:04
浮動少数じゃないけど関連ネタで

gccの3の途中からか、constant foldingのやりかたがガラっと変わって、
桁あふれや丸めを期待したコードのコンパイル結果が変わって困った、
という話があったような。

x/10*10がxになるとかだったかなあ。
926デフォルトの名無しさん:2007/04/15(日) 14:23:41
>>925
gcc4.2でやってみたけど期待した結果になるけど?
ひょっとしてこれが4.2の遅い理由?
927デフォルトの名無しさん:2007/04/15(日) 14:56:00
あーいや、桁あふれのほうだったかもしれん。
928`∀´>っ-○◎●:2007/04/15(日) 15:00:43
うんそれ精度保証だよ。
定数DIVを加算・乗算・シフトで代用するのは大昔からある最適化
DIV命令そのものがない石もあるし。
929デフォルトの名無しさん:2007/04/17(火) 18:41:38
確実にエイリアシングが起きないようなコードの書き方というのはあるのでしょうか?
930デフォルトの名無しさん:2007/04/17(火) 23:39:49
>>929
不確実にエイリアシングが起こるようにしたいの?
931デフォルトの名無しさん:2007/04/18(水) 01:53:38
>>929
エイリアシングって何?
932デフォルトの名無しさん:2007/04/18(水) 01:58:59
>>931
アンチエイリアシングの逆・・・かと、思ったんだが、
別にここはCG系のスレじゃないし、なんか他に意味あったっけ?
933`∀´>っ-○◎●:2007/04/18(水) 02:03:56
あんまりそわそわしないで

それなんてエイリアンソング?wwwwww
ダーリンおしおきだっちゃ


エスパーするとたぶんこれ
http://docs.hp.com/ja/B3906-90007/ch07s09.html

IntelアーキのL1は8Wayセットアソシエイティブ、つまり同じ下位アドレスに対して
8つのキャッシュライン・エントリを持てる。だからそんなに頻繁に起きるもんじゃない。
AMDは2Wayだから・・・(キャッシュ容量の割に性能良くないのはそのせい)
934デフォルトの名無しさん:2007/04/18(水) 04:24:30
int a = 0;
int &b = a;
a = b++;

こういうのもエイリアシング問題と言ったような気がする
935デフォルトの名無しさん:2007/04/18(水) 04:43:27
適切な日本語訳はないのか?
936デフォルトの名無しさん:2007/04/18(水) 06:53:31
別名化
937デフォルトの名無しさん:2007/04/18(水) 09:09:41
>>932
エイリアシングはCG用語ってわけじゃないよ。
和訳すると別名とか偽名みたいな意味で、色々なところで使われる言葉。
一番よく使われるのがサンプリング関係で、CGもその一種。

>>935
一語で表すと「別名」以上に適切な言葉は思い当たらないな。
動詞形なら>>936かね。
名前に限ったことではないので、全ての状況で適切というわけではないが…
938デフォルトの名無しさん:2007/04/18(水) 10:34:20
>>934
それただのエイリアス(別名)。

単に可読性のため意図的に読み替える機能であって、ポインタとは違ってアドレスを変えられない。
従って、予期しない動作はアホでも起こさないから避けるものでもなんでもない。
参照と実体の区別がつかなくなっちゃう痛い子はハンガリアン記法でも使っとけばいい。
そういうのは機能問題であって性能問題じゃないし。
普通に考えて下位アドレスの競合によるキャッシュの性能低下のことだと思うよ。
下位アドレスを自分で選べばいい。
たとえば配列を動的に確保するときに容量を多めに確保しておいて配列の開始アドレスを都度決めるとか。
939デフォルトの名無しさん:2007/04/18(水) 18:01:56
940デフォルトの名無しさん:2007/04/18(水) 18:50:46
>>939
それってエイリアシングがないと仮定してプログラマとコンパイラがコードを書けるというだけで、
実際にエイリアシングさせないのはプログラマの責任であることに変わりはないと思う。
941`∀´>っ-○◎●:2007/04/18(水) 20:29:58
結局、アドレスの重複か?w

>>940
賢いコンパイラなら、restrictポインタを受け取る関数を利用時、
コンパイル時に検出可能なものについてはエラーや警告を出せるかも。
942デフォルトの名無しさん:2007/04/20(金) 02:08:27
>>941
> 賢いコンパイラなら、restrictポインタを受け取る関数を利用時、
> コンパイル時に検出可能なものについてはエラーや警告を出せるかも。

エラーや警告ではなくて, 関数の最適化をもっと高度にこなせる

memcpy を inline 展開するときに
src, dst に重複した部分がなければチェックコードその他を省略できるとか
そっち方向の話だったはずだが...

あと, ライブラリーなんかも restrict 付いてればチェックコード手抜きでき
るんだっけか? > 識者
943`∀´>っ-○◎●:2007/04/20(金) 02:39:02
いや、呼び出し側で、プロトタイプにrestrict修飾が付いてれば・・の話

関数側はまあその通りでしょう
944デフォルトの名無しさん:2007/04/21(土) 03:40:08
intelコンパイラで、SSEを使っての計算を行おうとしています。

void func(float *x){
    *x=sin(*x);
}
for (int i=0;i<n;i++)
{
    func(&a[i]);
}

このような関数内で書き換えを伴う関数を呼び出すと、
loop was not vectorized: mixed data types
と出て、ベクトル化できません。何か方法はないでしょうか?
945デフォルトの名無しさん:2007/04/21(土) 04:52:34
>>944
実際のソースを頼む。
それから、sin()ではなくsinf()を使え。
946デフォルトの名無しさん:2007/04/21(土) 12:27:36
float func(float x) { return sinf(x); }
のほうがコンパイラにとっては優しかったりしないのかな
947デフォルトの名無しさん:2007/04/21(土) 12:35:40
>>946
優しいかどうかは知らんが、大差ないだろ。
手元にiccはないから、gccは後で試してみよう。
948デフォルトの名無しさん:2007/04/21(土) 18:31:58
一般的にintは参照よりは値渡しの方が速いね。
949デフォルトの名無しさん:2007/04/21(土) 18:54:10
処がだ、>944程度の関数だと(>944はfloatだけど)インライン展開されてしまうからどっちでも同じコードになるんだ。
950デフォルトの名無しさん:2007/04/21(土) 19:25:24
最適化って実際にやってみたら意外と
全然最適化してくれないなんてことも普通にあるし、
最適化に期待するのはあんまりよくない。

やってくれたら儲けものぐらいで捉えておくのがいいと思う。
951デフォルトの名無しさん:2007/04/21(土) 19:29:46
「やってくれたら儲けもの」ではなく、「やらせるもの」だろ。
952デフォルトの名無しさん:2007/04/21(土) 19:37:11
そういうスタンスだとうまく最適化できなかったときにテンパることになる。
953デフォルトの名無しさん:2007/04/21(土) 21:02:33
やらぬなら、自分で書こうIntrinsics
954デフォルトの名無しさん:2007/04/22(日) 00:00:16
今はポインタおっかけは普通にやってくれるんですかね
オレ古い人間だから>>946にしちゃうよ
955デフォルトの名無しさん:2007/04/22(日) 01:54:03
最速を目指すなら、
Intrinsics(or インラインASM) + sinhの近似値を自前で導出!

ttp://www.musicdsp.org/showone.php?id=175
956`∀´>っ-○◎●:2007/04/22(日) 01:56:23
SPEでテーブル参照って結構有効だな
L/Sの節約が必要になるが
957デフォルトの名無しさん:2007/04/22(日) 06:11:59
L/Sの狭さがレジスタの豊富さを打ち消してしまうSPE
958デフォルトの名無しさん:2007/04/22(日) 06:29:13
Cellのレジスタ何本だっけ?
959`∀´>っ-○◎●:2007/04/22(日) 06:34:43
PPE 32GR+32FR+32VR
SPU 128


逆だろレジスタの豊富さがL/Sの狭さを補ってるんだろ
960デフォルトの名無しさん:2007/04/22(日) 07:02:58
豊富なレジスタを使いたくても狭いL/S経由でしかデータを渡せないジャン。
961デフォルトの名無しさん:2007/04/22(日) 11:29:46
豊富なレジスタはレイテンシを隠滅する為だろ
962`∀´>っ-○◎●:2007/04/22(日) 11:31:32
ダブルバッファリングしてDMA転送で十分じゃん。メモリ帯域はCore 2のL2より速いよ・・・・合計でだけど
963デフォルトの名無しさん:2007/04/22(日) 12:10:37
逃げました
964デフォルトの名無しさん:2007/04/22(日) 13:22:32
あんまりやるとスレ違いな悪寒。
965デフォルトの名無しさん:2007/04/22(日) 15:17:11
団子ちゃんは何をしても許されるんですっ!
966デフォルトの名無しさん:2007/04/22(日) 18:21:09
まだ団子さんのやることに文句言う奴がいるの?
967デフォルトの名無しさん:2007/04/22(日) 20:23:42
団子くんは社会復帰のためのリハビリ中なんです。
生温かく見守ってあげてください
968`∀´>っ-○◎●:2007/04/22(日) 22:09:17
ニダ
969デフォルトの名無しさん:2007/04/24(火) 11:35:39
>>967
生暖かいと黴びが生えるぞ

#食い物の足が早ぇぇよ!
970デフォルトの名無しさん:2007/04/24(火) 20:26:10
C++でCライクなコードでかつ、Cよりも高速化できるC++で拡張されたものだけを
使ったC++コードを徹底するって案はどうかのお。
971デフォルトの名無しさん:2007/04/24(火) 23:36:02
for(i=0;i<MAX;i++){
 printf("%d");
 if( i%8!=0 ){
  if( i+1<MAX ){
   printf(",");
  }
 }else{
  if( i+1<MAX ){
   printf("\n");
  }
 }
}

これを分かりやすいままエレガントに書き直したいんだけど
どうしたらいい?
972デフォルトの名無しさん:2007/04/25(水) 00:45:47
for (i = 0; i < MAX; ++i) {
printf("%d");
if (i + 1 < MAX) {
printf("%c", i % 8 ? ',' : '\n');
}
}
973デフォルトの名無しさん:2007/04/25(水) 01:24:06
printf("%d") ←これは printf("%d", i)のこと?
974971:2007/04/25(水) 01:57:18
>>972
ありがとう!
if (i + 1 < MAX) {
の部分が、ループの判定とかぶるから なんとかしたいんだよね。

>>973
そうですすみません。ごめんなさい。
975デフォルトの名無しさん:2007/04/25(水) 02:18:43
>>974
for(i=0;i<MAX-1;i++){
printf("%d%c", i, i % 8 ? ',' : '\n');
}
printf("%d", i);
976デフォルトの名無しさん:2007/04/25(水) 02:18:49
for (int i = 0; i < MAX - 1; ++i ) {
  printf("%d%c", i % 8 ? ',' : '\n');
}
printf("%d", MAX);

こうとか。
977971:2007/04/25(水) 03:21:38
>>975-976
ありがとう! これで宿題が完成しました!
ほんとうに助かりました。
またお願いいたします。
978デフォルトの名無しさん:2007/04/25(水) 09:56:36
>>971
特定した
979デフォルトの名無しさん:2007/04/26(木) 01:07:32
このスレ読んで思ったのは,
「お前の脳ミソ最適化したほうがええんちゃうん???」
ってな, 奴等がほとんどだって事だ!
980デフォルトの名無しさん:2007/04/26(木) 01:52:39
>>979
団子ちゃんの悪口を言うな!
981`∀´>っ-○◎●:2007/04/26(木) 02:43:27
だんごやさんだにょ
982デフォルトの名無しさん:2007/04/28(土) 00:19:51
今日全てのforループのi++とかit++を++i, ++itなどに直しました。
ですが、逆に遅くなりました。5%くらい。
10回くらい測定しましたが。。。
こんなことってあるのでしょうか・・・
983`∀´>っ-○◎●:2007/04/28(土) 00:25:39
あるよ
984デフォルトの名無しさん:2007/04/28(土) 01:03:01
そのクラスの前置++と後置++がどう実装されているかの問題だしね。
オペレータを効率的に実装してなかったら意味がない。

最大限に効率を求めた実装をすると、後置++は一時オブジェクトが
必要な分だけ前置++よりも遅くなる。
985デフォルトの名無しさん:2007/04/28(土) 01:08:34
うーんそうなんですか。
やっぱ実測してみたいと分からないものですね。
986デフォルトの名無しさん:2007/04/28(土) 01:48:03
>>985
イテレータの++演算子の前置、後置に関しては実測以前の問題だよ。
984が書いている事をもう一度読んでごらん。
987デフォルトの名無しさん:2007/04/28(土) 02:29:33
最近のコンパイラなら後置++ は演算区間終了後に inc するようにちゃんと対処してそーな気もする。
988デフォルトの名無しさん:2007/04/28(土) 02:42:04
primitiveのみだけどな
989デフォルトの名無しさん:2007/04/28(土) 02:58:03
>>982は理屈とは逆の結果が出たと言っているようだが。
990デフォルトの名無しさん:2007/04/28(土) 04:01:03
X& operator ++(){ (*this)++; return *this; }
こういう実装だったんだろう。
991デフォルトの名無しさん:2007/04/28(土) 08:46:25
無限再帰?
992デフォルトの名無しさん:2007/04/28(土) 10:39:49
クラスとか operator とかそういう話じゃないだろ。
わざと言ってんだろうけど。

>全てのforループ

プログラム全体にわたってコンパイル後のコードが微妙にずれて
キャッシュの乗り具合がずれたんじゃねーの?
993デフォルトの名無しさん:2007/04/28(土) 10:59:15
ダンゴさんの一言が欲しいところだ
994デフォルトの名無しさん:2007/04/28(土) 11:01:21
>>993
>983

処で次スレは?
995デフォルトの名無しさん:2007/04/28(土) 11:11:25
イラネ
996デフォルトの名無しさん:2007/04/28(土) 11:29:25
いる
997デフォルトの名無しさん:2007/04/28(土) 11:36:15
団子が来てクソスレ化したので不要
998デフォルトの名無しさん:2007/04/28(土) 12:04:39
990 名前:デフォルトの名無しさん[sage] 投稿日:2007/04/28(土) 04:01:03
X& operator ++(){ (*this)++; return *this; }
こういう実装だったんだろう。

991 名前:デフォルトの名無しさん[sage] 投稿日:2007/04/28(土) 08:46:25
無限再帰?
999デフォルトの名無しさん:2007/04/28(土) 12:09:21
>>998
何その無駄なコード
1000デフォルトの名無しさん:2007/04/28(土) 12:10:45
>>999
>>982の理由
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。