トップページ⇒tech
992コメント455KB

くだすれFORTRAN(超初心者用)その4

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2009/01/24(土) 18:32:01
このスレッドは、他のスレッドでは書き込めない超低レベル、
もしくは質問者自身何が何だか分からない質問を勇気を持って書き込むスレッドです。
FORTRAN使いが優しくコメントを返しますが、
お礼はFORTRANの布教と初心者の救済と次期Fortran2008規格でのCOMEFROM文採用をお願いします。

●注意事項
・質問する前にGoogle等の検索サイトで検索しましょう。
・回答者にわかりやすい様に、質問内容はできる限り詳しく書きましょう。
・エラーの場合は起きた状況、環境(OS・コンパイラ・バージョン)、エラーメッセージも詳しく書きましょう。


●前スレ
くだすれFORTRAN(超初心者用)その3
http://pc11.2ch.net/test/read.cgi/tech/1196384126/

くだすれFORTRAN(超初心者用)その2
http://pc11.2ch.net/test/read.cgi/tech/1164121236/

くだすれFORTRAN(超初心者用)
http://pc8.2ch.net/test/read.cgi/tech/1138063703/


●関連スレ
FORTRAN �W
http://pc11.2ch.net/test/read.cgi/tech/1163319215/
0002デフォルトの名無しさん2009/01/24(土) 21:22:49
>>1
スレ立て乙です
0003デフォルトの名無しさん2009/01/25(日) 21:38:41
気象庁とかが推奨している、配列の代入にコロンを明示する方式でのスピード低下率の
まとめがあった。

ttp://www.ifremer.fr/ditigo/molagnon/fortran90/f90col.html

たとえば、以下のような場合

CALL( A )

CALL( A(:) ) −> ALLOCATE( TMP(SIZE(A)) ) ; TMP = A ; CALL (TMP) ; A = TMP ;DEALLOCATE(TMP)

ソースの意味的には同じだが、下の書き方だと、コンパイラが一度テンポラリに
Aの中身をコピーしてテンポラリを読んだりする実装がされたりする。

最近は少し賢くなったようだw
0004デフォルトの名無しさん2009/01/26(月) 01:32:56
それ最近の記事?
0005デフォルトの名無しさん2009/01/26(月) 06:57:57
へ〜
allocateして動的にメモリの空きを探して確保してコピーして、って
素で考えると手間がかかるだけな気がするけど、わざわざそうするということは
何か別な利得が発生するのかな?
000652009/01/26(月) 06:59:41
allocateして、は消してね。
a(:)が添字範囲全部の場合も、一部だけの場合でも両方対応するようにしたけど、
範囲全部の場合だけ別にする事を忘れただけなのかな?
0007デフォルトの名無しさん2009/01/26(月) 12:03:14
その記事は古いアルよ。
出ているコンパイラやOSを見る限り。
0008デフォルトの名無しさん2009/01/26(月) 16:23:18
じゃ、今は気にせんでおkってことね?
0009デフォルトの名無しさん2009/01/27(火) 21:09:52
do I = 1 , N
if(条件式) then
endif
done

と

do I = 1 , N
if( ! 条件式) cycle
done

は、やってることは等価だけど、速さも同じ?
0010デフォルトの名無しさん2009/01/28(水) 00:00:36
両方コンパイル時に止まるから速さも同j(ry

まあ、コンパイラにもよるから自分で試してみてくれ。
0011デフォルトの名無しさん2009/01/28(水) 01:53:01
最近大学でfortranを使い始めたのですが、インテルMKLを使うときはコンパイル時に
「ifortl」というコマンドを使うように指示されたのですがうまくいきません
どなたかわかる方いらっしゃいませんでしょうか?

環境は
OS Linux バージョン不明
コンパイラ Intel Fortaran 10.0
MKL Intel MKL9.1
コンパイラの購入時に「ifortl」コマンドを使うと自動でMKLのリンクが張られる〜
のような説明を受けたらしいのですが、使用すると引用したモジュールが見つかりません
という旨のエラーメッセージがでます。
リンクオプションをきちんと記述するとコンパイルできます
MKLへのリンクの環境変数が通っていないんだと思うのですが、
設定方法がわからない状態です
001292009/01/28(水) 02:42:17
>>10
>両方コンパイル時に止まるから速さも同j(ry
意味わからん。文法ミスって意味?
普通に使えてるんだが
0013デフォルトの名無しさん2009/01/28(水) 02:49:33
>>11
ウチのIntel Fortran 11.0 x86_64版には"ifortl"なるコマンドはないし、
ちょっとググってもそれらしい物はヒットしない。
とりあえず

file `which ifortl`

で ifortl の位置と種類を確認して、シェルスクリプトか何かなら

cat `which ifortl`

で中身を確認、書き換えられそうなら自力で修正
という感じで。
0014デフォルトの名無しさん2009/01/28(水) 03:00:18
>>11
「ifort」の間違いってオチじゃないよね…
0015デフォルトの名無しさん2009/01/28(水) 09:59:39
教官殿が気を利かせてMKLライブラリリンク用のを作ってくれたのかも知れんね。
13の通りwhichしてその内容をさらしてみるべし。
0016デフォルトの名無しさん2009/01/28(水) 10:00:09
MKLライブラリ、って書き方はおかしかったな・・。
0017112009/01/28(水) 12:33:23
>>13->>16
ありがとうございます、無事解決できました。
>>15
まったくその通りでした
うっかり「ifortl」という隠しコマンドでもあるのかと思ってました。
リンクを張ったつもり〜でしたが、実際は一部しか張ってなかったです
それにしてもなんというゆとりコマンド・・・
0018デフォルトの名無しさん2009/01/28(水) 12:45:50
そーいう余計なことは正直やめてほしいよなぁw
0019デフォルトの名無しさん2009/01/28(水) 17:55:31
ちょっと年代ものの他人が書いたf77のコードなのですが、

FW=CB(2)-CB(1)  //計算領域の幅を算出
CW=FW/NCX //幅をセル数で割ってセルの幅を算出

となる部分で、FWが1.33、NCXが200で、CWが6.65E-03となるはずが、
なぜか6.6500003E-3となっています。ちなみにFWはここで突如出現、
それ以外は特に型の宣言無くCOMMON文の中で定義されています。
何となく型の宣言が問題のような気がするんですが、原因と解決法
(ぴったり6.65E-3にしたい)を教えていただけませんか?
0020192009/01/28(水) 18:05:01
あ…すいません、FWもCOMMON文中に定義してありました。
0021デフォルトの名無しさん2009/01/29(木) 01:01:07
>>19
単精度なら有効桁からいって7〜8桁目にゴミが出てもおかしくない。
ゆえに気にするな。

フォーマットを与えずに*で書かせれば、自動的に精度の範囲内で出力するので
ゴミは見えなくなるだろう。フォーマットは浮動小数点での表現を単に何桁でも
十進法に直して書くだけだから、単精度でもF30.20とか書けば小数点以下20桁とか
書いてくれるが、有効数字的には6〜7個しか意味ない。

0022192009/01/29(木) 09:49:23
>>21
回答ありがとうございます。なるほど、7〜8桁目は有効数字外なんですね。
実害があってですね、粒子の位置の判定ををするとき、粒子の位置Xを
セルの幅CWで割って、

LCX=(X/CW)+0.999999 //Xが3.5、CWが1だとすると4.499999、整数に代入して4で4番目のセルに入る

みたいな処理があるんです。このとき、CWがずれてるとセルナンバーが大きいところだと、
想定外の変なセルに入っちゃう粒子が増えてきます。でも有効数字の問題だとすると、倍精度にしたとしても、
頻度は減るにせよ、根本的解決ではないってことになりますね?やっぱりこの処理自体に問題があるんでしょうか?
問題があるとしたらどういう方法にするべきでしょうか?
0023デフォルトの名無しさん2009/01/29(木) 10:17:31
小数点捨てにしよ四捨五入にせよ、数値誤差や丸め誤差やら打ち切り誤差で致命的に
結果が変わるようなモデルが悪い。そんなの窓から投げ捨てちゃえw
0024232009/01/29(木) 10:25:56
とはいっても粒子数がいっぱいあれば、離散化した箱の中の数が一個二個違うくらいではそんなに
変わらないだろうな。同じ問題は倍精度にしてもたぶん起こるよ。いまのCPUは単精度と倍精度で
ほとんど計算コストが変わらないので気が向いたら倍精度でやってみよう。
0025デフォルトの名無しさん2009/01/29(木) 11:05:29
>いまのCPUは単精度と倍精度でほとんど計算コストが変わらない
ほんとに?!
普通に考えれば倍精度になればデータが倍になるから、スピードは半分になるような
その辺考えてあえて倍精度じゃなく単精度を使ってるコードもあるじゃん
0026デフォルトの名無しさん2009/01/29(木) 11:33:48
>>25
いまの計算機ってメモリ・CPU間のデータ転送をクレバーに
さばくからあまり目立っては違わない。
ほとんど変わらないとは思わないけどコードにもよるけど
単精度でしても2割速くなれば御の字じゃないかな。
メモリ節約して粒子数なり格子数を増やす方にメリットがあると
当然単精度でするだろうけど。仮に2倍速になるにしても、
高々2倍のスピードを求めてあえて単精度で計算する、
というのは何か間違っていると思うよ。
0027デフォルトの名無しさん2009/01/29(木) 12:04:26
ディスクアクセスが非常に多い場合はそこでのロスを減らすために
単精度ですることは良くある
たくさんの測定データを読み込んで処理するときとかは特に
測定値だと元から倍精度の精度はないし
0028デフォルトの名無しさん2009/01/29(木) 13:25:25
>>22
はじめに一言。
四捨五入をしたいだけなら、NINTという関数があるのでそれを使うとよい。

ただNINTを使っても、十進表記にこだわると、今回の問題は解決しないかもしれない。
その理由を簡単に言うと以下のようになる。

Fortranでいうところの実数は、数学的な意味での実数ではない。
いわゆる浮動小数であって、有限個の有理数点で実数を代表させている。
ある種の区間をあらわす代表の数である。

その区間は、二進数表記で区切りのいい点で切っているので、十進数表記では
切りのいい点になっていない。

十進数で四捨五入しようとしても、そもそも閾値に幅があるのだから、その幅分の誤差が
出てもしょうがない。単精度ではそれが、有効数字7〜8桁目にくる。

数直線をかみそりで切り分けるイメージではなく、木材をのこぎりで切るイメージで
考えればおk。切るとき、おがくずが出て、切った材木にはのこぎりの歯の幅だけの誤差がでる。
それは避けられない。







0029デフォルトの名無しさん2009/01/29(木) 15:08:31
>>26
クレバーってどういう意味?データ転送のレイテンシ隠蔽をがんがってくれるって意味?
普通のアプリでは役に立つけど、数値計算のようなデータを単純にガバガバ読むプログラムじゃ
そういうテクの恩恵はあんまないでしょ。
メモリから演算器へ転送するデータ量が単純に倍になるんだから・・・
0030デフォルトの名無しさん2009/01/29(木) 15:30:11
違いは計算のコードや計算機の種類によりそうだけどね。
ベクトル化をすごく気にしたコードとか
一つのループを短くしたコードだとデータ転送の頻度がたぶん
すごく高いから29の通り単精度倍精度の違いは大きいだろう。
ループを細切れにせずに一つのループ内でながめな処理をするタイプだと
計算中に次に使うデータを取ってきたり更新の済んだ分をメモリに戻す暇が
出来そうだ。
0031デフォルトの名無しさん2009/01/29(木) 15:56:06
非線形系だと誤差って結構重要なんだよね
簡単に見えて意外に厄介
■ このスレッドは過去ログ倉庫に格納されています