> 最適化の指示内容(コンパイラオプション)によっては、アセンブラに落ちた時にSSE
(2/3
> /4…やMMXもあるのかな?)等に置き換えられますよね?
> 当然、その様にコンパイルされた物は処理時間は短くなります。
>であるならば、例えば動的にメモリ確保を行う場合でも影響が出て来るのかな?と思っ
た
> 次第です。
それが気になるのでしたら、コンパイルされたアセンブルリストを確認してみることを
お勧めいたします。コンパイルオプションを使用すればアセンブリコードを出力でき
ます。
プロジェクトの[オプション]-[出力ファイル]-[アセンブリの出力]で[アセンブリコード
とソースコード/FAs]を選択。
buf_aを使用している部分を確認してみたところ、
; 34 : memset(buf_a, 0, Asiz);
push 254 ; 000000feH
push 0
push esi
mov ebx, eax
call _memset
(中略)
; 38 : *buf_a = *buf_b;
mov al, BYTE PTR [edi]
こんなコードが出力されていました。まあ前後の処理の関係でコードは変わると思い
ますが、確保されているメモリのアドレスでコードを変えることはなさそうです。
> 確保されているメモリのアドレスでコードを変えることはなさそうです。
申し訳ありません。思い込みでよく確認せず書いてしまいました。
上記発言は撤回いたします。
> :
> 何かしらの処理
> :
の部分に
memset(buf_a, 0, Asiz);
memset(buf_b, 0, Bsiz);
memset(buf_c, 0, Csiz);
を書いたんですが、(1),(2)でコードが異なっていました。
(1)の方では; 19 : memset(buf_a, 0, Asiz);
push 254 ; 000000feH
mov esi, eax
push 0
push esi
lea edi, DWORD PTR [esi+254]
call _memset
; 20 : memset(buf_b, 0, Bsiz);
push 123 ; 0000007bH
push 0
push edi
call _memset
; 21 : memset(buf_c, 0, Csiz);
push 62353 ; 0000f391H
lea eax, DWORD PTR [edi+123]
push 0
push eax
call _memset
となっていました。
これを見る限りコンパイラはbuf_a, buf_b, buf_cが連続したアドレスに割りつけられ
ていることを利用してアドレス計算を行っているようです。そのために多少なりとも
効率的なコードを生成出来るようです。
実際に時間測定してみたらnew/deleteの回数の影響とは異なる時間差(funcの実行時
間に対して0.5%程度)が発生したのでその原因を追及したところ、アセンブルコード
の違いを見つけました。最初は測定誤差かと思ったんですが、そうではなかったよう
です。
他の不具合調査で返事が遅くなりました、すみません。
>solidさん
>こんな文書もありました
ありがとうございます。読みましたが…な感じです。
>PATIOさん
>提示された条件がかなり曖昧なのでどちらとも言いかねますね。
申し訳ありません。もっと具体例(実務沿った)方が良かったですね。
>仲澤@失業者さん
それなら納得です、ありがとうございました。
>bunさん
トリッキー過ぎな様な。。でも、コンパイル出来るんですもんね。
ありがとうございます。
>maruさん
>それが気になるのでしたら、コンパイルされたアセンブルリストを確認してみることを
>お勧めいたします。
はい、アセンブラは高速化の時点で見ています。
> 確保されているメモリのアドレスでコードを変えることはなさそうです。
申し訳ありません。思い込みでよく確認せず書いてしまいました。
上記発言は撤回いたします。
わざわざ有難うございます。
32bitCPUなら、4バイト単位(≒4の倍数)から始まるアドレスへのアクセスが一番効率が良
いですよね?
だとすると、ひとまとめにしたコード(この場合は1になります)のbuf_bはそれに該当しま
せん。
まぁ…最終的には、コードの読み易さorトリッキーのトレードオフなのでしょうかね?
皆さん、どうもありがとうございました。
解決とします。
最後に、ちょっとつぶやいておきます。
返事は無くてもOKです。
> トリッキー過ぎな様な。。でも、コンパイル出来るんですもんね。
> ありがとうございます。
トリッキーに感じられますか。。。
でも、よく考えてみてください。
生成と解放が同時期になる変数群です。
ということは、少なくとも func() という同一の処理をするために使用される
変数群だということです。
同一処理のために使用する変数群ってどこかで聞いたことありませんか?
そうです、クラスメンバ変数です。
構造体やクラスによるカプセル化ってまさにそのためにできたんではないでし
ょうか?
func()をメンバ関数にすれば、当たり前のクラス構造ができあがります。
以上
> 32bitCPUなら、4バイト単位(≒4の倍数)から始まるアドレスへのアクセスが一番効率
が良
> いですよね?
何故そう思うのですか?
アライメントの合っていないアドレスから複数バイトアクセスしたときにメモリアク
セスが複数回になるから?
そもそもバイト単位で処理を行うために char 配列にしているのだからメモリアクセ
スはバイト単位で考えればよい。アクセスしているデータがバイトならどのアドレス
でもアクセス時間は同じはず(キャッシュの影響を考えなければの話ですが)。
char 配列に文字列を入れて複数バイトで処理をするとしても、文字列として扱うため
にはstrxxxの文字列関数でメモリアクセスを行う。それらの関数にはcharのポインタ
を渡すが、それらの関数はアライメントの影響を考えない実装である(はず)。
従って
> 32bitCPUなら、4バイト単位(≒4の倍数)から始まるアドレスへのアクセスが一番効率
が良
は根拠がない。(と私は考えます。)
効率がよいにしてもたかが知れています。
>まぁ…最終的には、コードの読み易さorトリッキーのトレードオフなのでしょうかね?
私の考えではトリッキーなコードで高速化を図るより、コードの分かり易さを優先す
べき。コードの書き方で達成した高速化などたかが知れています。高速化を考えるな
ら、ちゃんとプロファイリングをしてボトルネックを探してからやらないと無駄な努
力になります。
ユーザの視点で判断するのがいいんじゃないかな。
>ユーザの視点で判断するのがいいんじゃないかな。
そうなんだけど、質問者の速度に対する要求がVC++のレベルを超えてるようにみえる
からでは?
本当に顧客の仕様として、そこまで速度を追求することが必要ならば、もう少し
CPUのことを学習した上でINTEL C等を使った方が有効ないかなと思う。
まぁー、だだ質問者が知識として知りたいだけなら、
質問者に判断を任せる。
でいいのかなと思う。
修正です。
> 本当に顧客の仕様として、そこまで速度を追求することが必要ならば、もう少し
> CPUのことを学習した上でINTEL C等を使った方が有効ないかなと思う。
↓修正
> 本当に顧客の仕様として、そこまで速度を追求することが必要ならば、もう少し
> CPUのことを学習した上でINTEL C等を使った方が有効だと思う。