No.16078![]() |
処理速度に関する実験 投稿者---Sciggepy(2004/08/06 00:20:40) |
||
ここでは、プログラミング環境が限定されていないので質問させて頂きます。 現在、数式評価関数を作っているのですが、他の環境では処理にどの程度時間を要するのか、ということを知りたいと思っています。 もし宜しければ、実験にご協力ください。 実験内容は、1+log(abs(sin(2+3))*4)/5という式(文字列)の評価(計算)を10万回繰り返すというものですが、私の実験では、次の結果が得られました。 OS: Windows XP SP1 CPU: Pentium 4 2.80GHz 処理に要した時間(最も多く得られた値) BCC 5.5の場合: 0.75秒 gcc 2.95.2(msvcrt.dllを使用)の場合: 2.453秒 (いずれも最適化なし) ソースは入りきらないので(約16KB)、ここに置いておきます。(以前作ろうとしていたプログラムの残骸を強引に書き換えたため、かなり煩雑です。スタック領域が充分でない場合は、実行しないでください。) 3つのファイルをダウンロードし、test.cをコンパイルするだけで、実験用のアプリケーションができます。 実験結果のうち、私が知りたい情報は、OS、CPU、コンパイラ、処理に要した時間(5回程度試行し、その中で最も多く現れた値、もしくは、平均値をとります。)の4つです。 時間があれば、ぜひご協力ください。 |
No.16087![]() |
Re:処理速度に関する実験 投稿者---シャノン(2004/08/06 03:12:08) |
||
OS:WinXP Pro SP1 CPU:Celeron 2.2GHz コンパイラ:VC++.NET 2003 最適化無し: 最大値:3.064 最小値:2.703 中央値:2.864 平均値:2.8598 最適化あり: 最大値:3.254 最小値:2.533 中央値:2.593 平均値:2.7372 コンパイラ:VC++ 2005 Express Beta1 最適化なし: 最大値:2.733 最小値:2.653 中央値:2.723 平均値:2.699 最適化あり: 最大値:2.543 最小値:2.353 中央値:2.493 平均値:2.467 VC++2005 め、βのくせに速い… |
No.16088![]() |
Re:処理速度に関する実験 投稿者---シャノン(2004/08/06 03:14:47) |
||
VC++ は厳密にはコンパイラじゃなくて IDE だけど、まぁいいよね。 2003 は Enterprise Development Edition だったと思います。多分。 |
No.16090![]() |
Re:処理速度に関する実験 投稿者---tetrapod(2004/08/06 10:31:42) |
||
DELL のノート P3-700MHz/815P/W2KSP4 では cygwin (gcc-3.3.1) 最適化あり (gcc -O -g test.c -lm) 6.309x5 VC++6SP6 最適化なし (cl test.c) 4.887x3/4.897x2 VC++6SP6 最適化あり (cl -Ox2 test.c) 4.085x5 となりました。 hppa2.0w-hp-hpux11.00 では bus error (core dumped) します。 bigendian マシンでは動かないのかも? |
No.16117![]() |
Re:処理速度に関する実験 投稿者---Sciggepy(2004/08/08 23:45:22) |
||
>hppa2.0w-hp-hpux11.00 では bus error (core dumped) します。 bus errorですか...確か、メモリのアクセス境界を越えてアクセスしたための起こったものだと思うのですが(UNIXユーザーではないので、よく分かりません。)、そのエラーはどこで起こっているのでしょうか。 私としては、 *((double *)pResult)=(double)(r); が怪しいと思います。 |
No.16120![]() |
Re:処理速度に関する実験 投稿者---tetrapod(2004/08/09 08:33:16) |
||
eval.c:476 dRes=OPTD(op1)+OPTD(op2); で SIGBUS です。 OPTD の実装は #define OPTD(op) (*((double*)(op+1))) ここで op1=0x40003468 op2=0x40003480 となっているのを確認しました。 「 double 変数は 8byte 境界からでないとアクセスできない」 ため、 BUS Error になったのでしょう。 ix86 では奇数バイトからのワードアクセスが認められていますが (パフォーマンスを犠牲にした上で) たいていの RISC 系 CPU では認められていません。 この辺修正すれば ix86 でも速度向上が望めるかもしれません。 |
No.16122![]() |
Re:処理速度に関する実験 投稿者---Sciggepy(2004/08/09 10:21:21) |
||
ありがとうございました。 一応、 static double OPTD(const char *op) { double d; memcpy(&d,op+1,sizeof(double)); return d; }という方法も考えたのですが、速度が少し落ちるので、double型の値を入れるときは、sizeof(double)境界にします。 あと、文字列を扱っていた頃の名残で、ヒープ領域を何度も割り当てたり開放したりしていますが、その部分も全て取り払うことにします。 |
No.16127![]() |
Re:処理速度に関する実験 投稿者---Sciggepy(2004/08/09 17:42:46) |
||
書き換えが完了しました。最初のものと比べると、1.5から2.5倍程度速度が上がり、ソースも小さくなりました。 まさしく、一石二鳥です。 後の人が見て内容不明にならないように、ソースは元の場所のものを置換して置いておきます。(全部あわせても、たったの12KBなので。) |
No.16135![]() |
Re:処理速度に関する実験 投稿者---tetrapod(2004/08/10 10:12:40) |
||
hppa2.0w-hp-hpux11.00+gcc-3.4.1 でうまく動きました(要修正1箇所) gcc-3.4.1 gcc -O test2.c -lm で 1.400秒というところです。 先の DELL+VC++6 cl -Ox2 test2.c だと 0.66秒でした # PC が速いというよりは旧式な WS が遅いというべきか... 修正点は test.c/test2.c の printf (tm2-tm1)/CLOCKS_PER_SEC だと整数型に評価され %f に型一致しないので (double)(tm2-tm1)/CLOCKS_PER_SEC にする必要があります。 # 前回言わなかったけど... # そちらで表示されている値って正しいのだろうか? |
No.16137![]() |
Re:処理速度に関する実験 投稿者---たか(2004/08/10 14:19:05) |
||
メモリインターリーブをかけているとアラインミスで大幅にメモリアクセスが遅くなるようです。 元のプログラム Pen4 2.8G(Single Channnel) + VC7.1(最適化なし) 1.833 AthlonXP 2500+(Single Channel 4Bank Interleave) + VC7.1(最適化なし) 8.641 改良プログラム Pen4 2.8G(Single Channnel) + VC7.1(最適化なし) 1.266 AthlonXP 2500+(Single Channel 4Bank Interleave) + VC7.1(最適化なし) 1.268 単にAMD系のメモリ周りの弱さが出たのかも知れませんが。Athlon64だと もっといい値が出るかも知れません。 |
No.16138![]() |
Re:処理速度に関する実験 投稿者---たか(2004/08/10 14:27:11) |
||
失礼。OSを書くのを忘れていました。 両方ともWindowsXPSP1です。 |
No.16142![]() |
Re:処理速度に関する実験 投稿者---Sciggepy(2004/08/10 21:03:30) |
||
>改良プログラム >Pen4 2.8G(Single Channnel) + VC7.1(最適化なし) >1.266 >AthlonXP 2500+(Single Channel 4Bank Interleave) + VC7.1(最適化なし) >1.268 改良プログラムとは、新しく置いたプログラムのことですか? OS、プロセッサは同じようですが、私の環境では、 test.c(最適化なし、試行回数=5) BCC5.5: 0.391*1, 0.407*1, 0.390*1, 0.406*2 gcc 3.1.0(MinGW-msvcrt.dll): 0.859*3, 0.875*1, 0.843*1 という結果になりました。 ここまで値に差が出るのは、メモリへのアクセス速度などの差によるものでしょうか。私のPCでは、 DDR SDRAM DIMM 320MHz 256MB*2 のメモリを使っています。 |
No.16143![]() |
Re:処理速度に関する実験 投稿者---たか(2004/08/10 21:33:04) |
||
申し訳ない!timeではなくて処理結果の方を見ていました。 そうです。改良後とは8バイトアラインにされた新しいプログラムの方です。 (test1.c) Pentium4 + VC7.1(最適化無し) 0.656 Pentium4 + BCC5.6.4(最適化無し) 0.547 Athlon2500+ + VC7.1(最適化無し) 1.688 Athlon2500+ + BCC5.6.4(最適化無し) 0.719 改良前の物は変わりません。 こうしてみるとAMD系はVC7.1と相性が悪く、Pentium4向けのコードを 吐いているのではないかと思えてきます。 |
No.16144![]() |
Re:処理速度に関する実験 投稿者---たか(2004/08/10 21:39:21) |
||
そしてお察しの通り、Pentium4のメモリはPC2100 512MB×2です。今と なっては古いですね。しかもマザボの方でメモリインターリーブがかけ られない(845E)ですので余計にレイテンシの影響が出ているのだと思います。 PC3200 Dual Channel + HT にしようかと何回か思いましたが、Athlon64も 一般的になってきたことですし思いとどまっています(実用上全く問題は ありませんので)。それよりAthlonXPはPC2700なのに遅いですよね。CPUの 本当のクロック周波数が1.833GHzと遅い(Barton)のが原因かもしれません。 |
No.16145![]() |
Re:処理速度に関する実験 投稿者---Sciggepy(2004/08/10 22:54:36) |
||
>申し訳ない!timeではなくて処理結果の方を見ていました。 !! >Pen4 2.8G(Single Channnel) + VC7.1(最適化なし) >1.266 >AthlonXP 2500+(Single Channel 4Bank Interleave) + VC7.1(最適化なし) >1.268 正常に動作すると、 retval=1.268870 が出力されるはずですが... ちなみに、EVMAX_TOKを16にしたところ、少し速度が上がりました。double型で信頼できる桁数は15か16程度なので、妥当な値だと思います。(数値や関数の後は必ず0(演算子、または、空の要素)がくるので、EVTKLITEM構造体のtokenをすべて文字で埋めても問題ありません。) |
No.16146![]() |
Re:処理速度に関する実験 投稿者---たか(2004/08/10 23:07:31) |
||
>正常に動作すると、 >retval=1.268870 >が出力されるはずですが... はい、端折って書いていました。1.266という時間はぱっと見ただけなの で見間違えたのだと思います。1.268は皆さん小数点以下3桁しか書いて なかったのでそれに従いました。全部違っていたのですね・・・・ AthlonXPはあれから何度かテストをしてみましたが、Pentium4並の速度 が出る場合もありました。(2500+と銘打っているんですからね) バックグラウンドで何か動いていると正しく計測できませんね。ただ、 今はそいつが止められない状態でして。 |
No.16152![]() |
Re:処理速度に関する実験 投稿者---Sciggepy(2004/08/11 12:34:30) |
||
>EVTKLITEM構造体のtokenをす>べて文字で埋めても問題ありません。 (自分へのツッコミ)嘘です。そんなことはありません。最後の要素が16文字以上になると、確保した領域を超えた部分へのアクセスが発生します。 eval_fmltotokの if(ct<EVMAX_TOK) pTKL[idx].token[ct++]=szFormula[i]; の部分は、やはり if(ct<EVMAX_TOK-1) pTKL[idx].token[ct++]=szFormula[i]; と書き換えるべきでした。 |
No.16141![]() |
Re:処理速度に関する実験 投稿者---Sciggepy(2004/08/10 20:12:13) |
||
>修正点は test.c/test2.c の printf >(tm2-tm1)/CLOCKS_PER_SEC だと整数型に評価され %f に型一致しないので >(double)(tm2-tm1)/CLOCKS_PER_SEC にする必要があります。 処理系によっては、整数型として評価されるのでしょうか? BCC 5.5、gcc 3.1.0(MinGW)では問題ありませんでした。 ># 前回言わなかったけど... ># そちらで表示されている値って正しいのだろうか? 何の値のことですか? retvalは、電卓の値と比べると、小数点下16桁目まで正しいようです。 |
No.16147![]() |
Re:処理速度に関する実験 投稿者---tetrapod(2004/08/11 08:21:26) |
||
>処理系によっては、整数型として評価されるのでしょうか? >BCC 5.5、gcc 3.1.0(MinGW)では問題ありませんでした。 CLOCKS_PER_SEC の定義ですが、 VC++6.0SP6 : #define CLOCKS_PER_SEC 1000 BCC5.5.1 : #define CLOCKS_PER_SEC 1000.0 hpux11.00 : #define CLOCKS_PER_SEC 1000000 cygwin : #define CLOCKS_PER_SEC 1000 となっていて BCC5.5.1 以外はすべて整数型です。 clock_t は整数型でなければならないので (tm2-tm1)/CLOCKS_PER_SEC は BCC55 以外ではすべて汎整数型に評価されます。 # cygwin(gcc-3.3.1) と mingw で CLOCKS_PER_SEC 違うのだろうか? >何の値のことですか? >retvalは、電卓の値と比べると、小数点下16桁目まで正しいようです。 retval ではなく時間の値ですね。 %f で整数型の数値を表示することはできないので。 |
No.16149![]() |
Re:処理速度に関する実験 投稿者---Sciggepy(2004/08/11 11:23:39) |
||
># cygwin(gcc-3.3.1) と mingw で CLOCKS_PER_SEC 違うのだろうか? gcc 3.2.3(MinGW 3.1.0)では、CLOCKS_PER_SECは((clock_t)1000)と定義されていました。 試しに、 printf("retval=%f\ntime=%f\n",d,(tm2-tm1)/CLOCKS_PER_SEC); として実行したところ、timeの値は0になりました。 ただ、前の2.95.2では問題なかったので、ヘッダファイルを確認すると、CLOCKS_PER_SECは1000.0と定義されていました。 (ダウンロード元 ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/mingw32/gcc-2.95.2) |
No.16150![]() |
Re:処理速度に関する実験 投稿者---シャノン(2004/08/11 12:26:53) |
||
>># cygwin(gcc-3.3.1) と mingw で CLOCKS_PER_SEC 違うのだろうか? 最初に言っとくべきかなー、とも思ったんですが。 VC++ 7.1 でも 1000 です。 なので、( tm2 - tm1 ) を勝手に double にキャストさせていただきやした。 そーでないと 0.000000 になっちゃうので。 |
No.16153![]() |
Re:処理速度に関する実験 投稿者---たか(2004/08/11 13:07:54) |
||
>VC++ 7.1 でも 1000 です。 >なので、( tm2 - tm1 ) を勝手に double にキャストさせていただきやした。 >そーでないと 0.000000 になっちゃうので。 あ、言いませんでしたけど私も勝手にキャストさせていただきました。 このベンチマークは(どのベンチマークもそうだろうけど)二次キャッシュ の容量とメインメモリのアクセス時のレイテンシが大きく影響するよう です。 |
No.16101![]() |
ご協力ありがとうございました。 投稿者---Sciggepy(2004/08/06 17:28:32) |
||
参考までに、他の実験の結果です。マシン、OSは同じです。 最適化ありの場合(試行回数=5) bcc32 -WC -O2 test.c 0.765(秒)*2(回) 0.766*3 (速度を最適化した方が遅くなる。) gcc -O test.c 2.031*2 2.046*3 (BCC強し(@@>)) vectorからダウンロードしたCalcXとの比較 (CalcXではabsが使えないため、式を1+log((-1)*sin(2+3)*4)/5に変更して実験しました。) コンパイラ: BCC 最適化なし eval 0.922*3 0.937*1 0.938*1 CalcX 7.547*1 7.516*2 7.531*1 7.515*1 ご協力ありがとうございました。 |