トップ 最新 追記

Orz日記 by Akio Morita

ToDo:

  • 15 SAD Fit[]回りの障害事例の解析
  • 10 smart pointer版PEGクラスの再実装(Left Recursionまわり)
2006|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|06|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|07|08|09|10|11|12|
2013|01|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|06|07|08|10|12|
2016|01|02|03|05|06|08|10|11|
2017|01|02|03|04|05|06|07|09|10|11|12|
2018|01|02|03|04|06|07|08|09|10|11|12|
2019|01|03|04|05|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|

2008-02-06 [長年日記]

_ [SAD]Beam Line Element名での Caseの扱い

掲示板 にも書きましたが、Beam Line Element名での Caseの扱いが変です。 MAINレベルとか SADScript関数(LINE/Element/...)では Case Preserveかつ Case Sensitive Matchなんですが、FFSコマンドラインは Case Preserveで無い上に Case Sensitive Matchのようで、小文字混じりの要素を FITや FREE/FIXに 使えないことを見付けました...Orz

コマンド名を Case Insensitive Matchするのでなく、問答無用で 全てのtoken(コマンド名以外を含む)のCaseを正規化してから Case Sensitive Matchをかけてるっぽいのですが...

少なくともシステムの一貫性が損なわれている部分は修正すべきなのですが、 正しい仕様はなんなんでしょう?

_ [SAD]頭痛くなって来た...

script/bench2.sadにて、RFMARK2と宣言した要素を fit rfmark2 ...で参照するコードを発見

つまり、過去のコードは FFSコマンドラインでの要素名に対する Case Insensitive Match若しくはCase Normalizationを 期待している...頭痛くなって来たぞ Orz

たぶん、後方互換性を維持するには Case Matching Ruleを制御する フラグか関数を導入する必要があるとみた(Case Normalizationを 強要すると LINE/Element関数が Case Sensitiveで無くなるので、 それに依存したコードの互換性を損なうし...全ての要素名が 表れる部分にCase Normalizationを実装するのは面倒)

_ [SAD]Fortran system関数修正

Fortranコンパイラが system INTRINSICを提供しない際に使う system_()のプロトタイプが間違っていたというか、 間抜けなことに system() INTRINSIC soubrutine互換を実装してた。 呼び出し側で使っているのは、system() INTRINSIC functionなんだよね... (g77/gfortranにはINTRINSICがあるので関係ないです。ifcで問題が...)

やっぱ、プロトタイプ宣言の無い言語で大規模開発は厳しい気がする


2008-02-08 [長年日記]

_ [KEKB]運転再開

どうやら、無事に運転再開した模様

_ [SAD]CONVCASE/PRSVCASEフラグ実装

FFS command lineで、字句解析器がシンボル・コマンドを Upper Caseへ 強制変換してしまうので、小文字を含んだ element nameをFIT等で参照 できない問題への対処を始める。

PRSVCASEを指定すると element nameを Case Preservingに扱い、 NOCONVCASEを指定すると 字句解析器での Case変換を無効化する。

後方互換性のために、起動時はNOPRSVCASEかつCONVCASEで実装

現時点では、PRSVCASEフラグは FFS command全てのコマンドで 有効なわけでは有りませんが、通常使用する主要なコマンドは サポート出来ていると思います。

本日のツッコミ(全1件) [ツッコミを入れる]

_ 三菱 田中 [またLogBrowserの鯖が見えないようです ]


2008-02-11 [長年日記]

_ [LHC]Coupling/Dispersion Correctionの荒っぽい評価

IP Coupling/Dispersion Knobまわりの話の一環として Coupling Correctionの荒っぽい評価をしてみる。

6極のミスアライメントをソースとする Coupling/Dispersion Errorを アーク部のSkew Q.で補正してみる。測定と補正モデルを作るのが 面倒なので、各直線部の真ん中で R1-4を拘束して Matchingするモデルを 採用する。当然、EYと EPYに誤差が残るので、EYを条件に追加すると Matching仕切れない....

各アークに Skew Q. 4台ではこれは当然の結果だが... なんで、6台入れなかったんだ?

_ [SAD]PRSVCASE/CONVCASEフラグ

マニュアルに増設したフラグの記述を追加した。

動作としては、CONVCASEを切ればFFSコマンドラインは問答無用で Case Sensitiveになるが、コマンドやオプション類は全て大文字で 無いと受け入れられないので要注意

また、PRSVCASEの実装状況(Rev.1362)だが ielm()経由で参照している 部分を中心に修正しているので、一部抜けがありえます(temat()/tmatch() 経由の参照が有ることが判明している。改修したファイル内に関しては、 一応修正してあるが...)

改修済みコマンドリスト

  • DRAW
  • MAT_RIX
  • RENUM_BER
  • ALI_GN
  • LAT_TICE
  • PS_NAME
  • KILL
  • KI_CK
  • BALS
  • VBUMP
  • COR_RECT
  • FIT
  • TRC_OD
  • MEA_SURE
  • COUP_LE
  • DECOUP_LE
  • INDEP_ENDENT
  • DISP_LAY
  • FREE
  • FIX

実用上は、DISP,FIT,COUP,FREE,FIXだけ 使えれば十分な気がする

どうしてもこれ以外のコマンドで小文字の要素名が必要な場合は、 NOCONVCASEに切替えてください


2008-02-12 [長年日記]

_ [FreeBSD]NFS mountが Default TCPに

CURRENTでは、TCP NFS mountが defaultになったらしい。

なんでも、現代的なGiga bps以上の帯域を持つネットワークでは TCPに切替えてもUDPに対して有意な性能の劣化も無く いろいろ恩恵があるそうな...これも、時代の流れですかねぇ


2008-02-13 [長年日記]

_ [SAD]Backslash escape in Fortran

SAD/Tkinter周りで Backslash escape問題(GCC 4.2.x以前では発症しませんが)を修正。 原因は、OBJ_BACKSLASH_ESCAPEの更新し忘れ Orz

これは、バックポート必要だよね(たぶん Tru64には影響する)

_ [SAD]Tcl/Tk8.4.18サポート

なんか、また configure周りがいじられてる...

_ [SAD]疑似乱数発生器試験 by Tracking

KEKB HER Crab Opticsを使った Tracking(RFSW/RAD/FLUC付き)で 疑似乱数発生器の置き換え前後を比較する。

RADと FLUCで放射減衰と量子励起による拡散に疑似乱数列が使われているので、 コードの置き換え(PRNG本体の置き換え&iseedのインライン化された線形合同 法を関数呼び出しに置き換えた)に失敗している部分をなめると結果に 違いが出るはずというのが、試験動機です。

試験内容は、粒子数1000個の初期分布を与えて 1000ターンのTrackingを行い結果と消費CPUタイムを比較する。

まず、疑似乱数発生器に Random/SAD pluginを使った場合

coderesulttime/turn
CVS MAINreference5.9914
amoritamatch5.9528
amorita-noarraymatch6.1047

使用された範囲のコードでの疑似乱数列参照の書き換えは成功している模様。

amoritaと amorita-noarrayの実行速度差を見ると、 疑似乱数生成ループを新設したtran_array_,tgauss_array_ (乱数配列を取ってくるAPI)へ置き換えたが速度向上に 寄与しているように見える。 また、インラインルーチンを関数呼び出しへ置き換えことに伴う速度低下を 乱数配列生成APIによる速度向上でカバーできたようである。

続いて、SeedRandom[]を使って疑似乱数列を Random/SFMT pluginに切替えた場合

coderesulttime/turn
CVS MAINmis-match6.0000
amoritareference6.0035
amorita-noarraymatch6.2041

CVS MAINの疑似乱数発生器は線形合同法固定(Random/SAD相当)なので 一致しない、きちんと違う疑似乱数列が適用されていることが判る。

また、処理速度の悪化の問題はないようである。

_ [SAD]Backporting to CVS MAIN trunk

やっぱり、Backslash escapeの問題は、実用上問題がでるバグなので CVS MAIN trunk側にバックポートを実施。 ついでに、Tcl/Tk 8.4.18サポートもバックポートする。

しかし、CVS MAIN trunk側の更新ルールのよくわからない version番号と commit logをまともに残さない風習は改善しないのだろうか Orz


2008-02-14 [長年日記]

_ [FreeBSD]なんかSAでてますね

FreeBSD-SA-08:03は sendfile(2)経由で読みだし権限の無いファイルを socketへ送出できる。

FreeBSD-SA-08:04は IPsecの実装不備から IPv6パケットを送り込むことで kernel panicを誘発できる。

FreeBSD-SA-08:04は、リモートからの DoSに使えるけど IPsecを 組み込んでないカーネルには効果なしの模様。


2008-02-17 [長年日記]

_ [SAD]g95サポートという変更

writeb@tfprinta.fの変更は、IFCサポートぶち壊しな気がする

write文での改行制御などの標準外 format指定は、 激しくコンパイラ依存で、\$を後ろに付ける改行制御は IFCは受け付けなかったような...

IFCサポートを入れるときに、G77/DEC Fortran/Intel Fortran 全てで共通に使える改行制御を探すのにえらい苦労した記憶が... (I hope the below works for all compilers...って 希望するだけなら簡単だけど、それでは世の中のコンパイラは 動かないんだ...)

絶望した!I/Oを再定義出来ないのに、ベンダーが勝手に I/O書式制御を拡張する Fortranコンパイラに絶望した!

(2008/02/19追記)

IFCだと#文字の characterを表示するのにa#という 書式指定も NGというか期待と違う動作をする

a#は、i#と同様に #bytesな characterと解釈されるので "abc"a3でフォーマットすると出力は" a"となり、 一文字の character "a"を先頭に空白を付けて 3byte幅で出力する。


2008-02-19 [長年日記]

_ [SAD]CVS MAIN trunkはg95サポートで荒れてますね

状況はかなりひどいようなので安定するまで バックポートは凍結かな?

  • GNU make的な enbug(conditional-else-endifはネスト出来ないと infoに書いてある)
  • Intel Fortran portを破壊(まあ、運転では使ってないのでセーフ?)
  • g95 0.91(20070129)ではコンパイルできるが、出力がバグる(g95サポートになっていない!)
  • 新 writeb@tfprinta.fには、コンパイラ実装依存な香りが漂っている

GNU makeに関しては、既存の amsad/alsad/acsadでの makeで 発覚するはずなので、既存の環境での make試験をせずに commitしたのは明白。

CVS MAIN trunkに関しては KEKBの運転で使っている以上、 運転環境の構築で問題が出る変更を入れるのは NGなはず。

writebで使っている character*Nな bufferへの write文の結果だが、 Fortran規格をチェックしていないのだが、出回っているコンパイラの 出力を比較する限り実装依存な気がする。 全てのコンパイラで動くことを期待するなら、Fortranの標準規格の 範囲内で書くべきで、可能ならコンパイラの実装バグを避けるよう 実装が安定している範囲で書くべき。

Fortranの場合、1文字入出力等のプリミティブなI/Oが標準規格に無いので、 Cと異なりread/write文の実装が腐っているからといって置き換えを 作れないところが頭痛の種ですね。プリプロセッサで open/close/read/write系を Cの関数に置き換えるというのは原理的には 可能だが、それは Fortranの部分コンパイラを作ることであって、 腐った処理系の再実装に相当する。


2008-02-20 [長年日記]

_ [SAD][Fortran]Fortranの編集記述子

SAD掲示板では、writeb論争が繰り返されておりますが、 write文と編集記述子の仕様を求めて Web上を彷徨い歩くはめに...

まずは、一個発見♪ XL Fortran 95のマニュアル には、Q\$IBM拡張とある。 明らさまに拡張と書かれている以上、Fortran95の編集記述子には 改行抑止制御は実装されていないことに...

Fortran2003には、この拡張は入っているのかな? Fortran2003完全準拠のコンパイラもまだ無いのに、 Fortran2008(2003のマイナーアップデート)が出てくるという話だが...

あと、編集記述子の要素数より多い要素をWRITE文に記述した場合の動作定義が判らない... Orz

HP Fortranのマニュアル にそれらしき記述を発見、それによると編集記述子の 最後まで使いきったら、一度出力終了して、再度出力を始める際に 基本的には制御は、入れ子レベル 1 の右端のグループの反復数に戻さる らしい。 さらに、入れ子レベル 1 の右端のグループに反復数が存在しなければ、制御はそのグループ自体に戻れ入れ子レベル 1 のグループが存在しなければ、制御は書式仕様内の最初の編集記述子に戻されるそうなので、同じ形式("A1")で 長さnのinteger*1配列から 文字列を吐き出させる場合(\$,nA1)(\$,A1)は 同値ということか。

ふむ、少なくとも HP Fortranでのコードは簡単に書けることが判った。

ただ、これだけだとHP Fortranの実装がそうなっているのか Fortran規格でそう実装すべきを規定されているのか区別が付かない。

ふむ、 HP Fortranの編集記述子の 解説によれば、\$の改行抑制と同様の機能で 停留入出力と呼ばれ る機能が有り、これは Fortran90規格に含まれるようだ。 (やはり、\$は HP Fortranでの拡張と書かれている)

改行制御をまとめると、

  • Fortran90だと、停留入出力を使えば、改行を抑制した出力が可能。
  • Fortran77の標準規格内では、逆立ちしても無理

ということか

write文に ADVANCE='NO'を指定して停留出力を使うと 最後の改行が抑制されるが、編集記述子の数が不足して使いまわされる際に 出力の停止と再開の間で改行が出力される (g95-0.91/gfortran-4.2.4pre/ifort-8.1で確認)

たぶん、Fortran90的には (#a1)な編集記述子を合成して、 ADVANCE='NO'で出力すれば OK、 IBM拡張を当てにするなら (\$,a1)で十分

ただし、ADVANCE予約語は g77の Fortran90モードでは 実装されていない Orz

_ [SAD][Fortran]writebないでの form合成

write(form,*)lで整数lを文字列化した際に、 右詰め・左詰めの違いが出ることに関して SAD掲示板で下記の試験結果を

--- begin test.f ---
      integer num
      character*12 form
      num = 12
      write(form,*) num
      write(*,*)'form=[',form,']'
      end
--- end test.f ---

0. DEC Fortran on acsad0
% f77 test.f && ./a.out
 form=[          12]

1. GNU Fortran (GCC) 4.2.4 20080213 (prerelease)
% gfortran42 test.f && ./a.out
 form=[          12]

2. GNU Fortran (GCC) 3.4.6 [FreeBSD]
% g77-34 test.f && ./a.out
 form=[ 12         ]

3. Intel(R) Fortran Compiler for 32-bit applications, Version 8.1    Build 20060606Z
% ifort test.f && ./a.out
 form=[          12]

4. G95 0.91
% g95 test.f && ./a.out
 form=[ 12         ]

報告したが、整数変数記述子は右揃えなので write文に真面目に編集記述子(I12)を付ければ 全ての環境で右詰めで出力されることに、思い至った。 もし、そうでなければ...その Fortranコンパイラは壊れている。

_ [SAD][Fortran]writeb on g95

どうやら、g95はwrite文でのフォーマット変換の解釈が厳格で、 文字型の編集記述子aへ整数型を渡すのは不正らしい。

Fortran runtime error: Expected CHARACTER for item 1 in formatted transfer, got INTEGER. If you want to make character descriptors typeless, compile with -fsloppy-char

だそうです

本日のツッコミ(全1件) [ツッコミを入れる]

_ alexd259 [Very nice site!]


2008-02-21 [長年日記]

_ [SAD][Fortran]FortranのI型編集記述子

整数を右詰めw桁に編集する記述子Iwですが、 一部のコンパイラではw=0のときは表現可能な 最小の桁数に編集するという意味を持つ (Nag Fortranのマニュアルで見付けた)ようですが、 案の定 g77では動きません。

Intel Fortran 8.1/gfortran-4.2.4/g95-0.91では、 使えるところを見ると Fortran90/95辺りに入っている?

XL Fortranのマニュアル だと "Fortran95は例外です" とあるから、 正式規格には入っていないのか...それともマニュアルの誤訳?

_ [雑記]Xserve RAID販売終了

なんだって〜!

KEKB制御室に何台か置いてあったよな...サポートどうなるんだろう?

_ [KEKB]日本時間 23:46現在 Optics Correction中?

今回の定期メンテ後の立ち上げは、ゆっくりしているようだ

本日のツッコミ(全1件) [ツッコミを入れる]

_ 管理人さん [Xserve RAID販売終了 購入から4年経過、そろそろだと思っていた。]


2008-02-22 [長年日記]

_ [SAD][FreeBSD]新しい devel/libffi

長らく放置されていた、ports/devel/libffiが新しくなっている。

SAD用のFFIインターフェースは libffiでいきますかね? printf見たいに、引き数列のフォーマットを渡して 外部関数を呼び出すような感じで...

_ [SAD][Fortran]CR+LFの呪い

SADの Binary Read/Writeのベンチマークで発見

Intel Fortran 8.1 + FGETC intrinsic functionの組合せで、ファイル上のLF(0x0a)を読むと FGETCは CR(0x0d)+LF(0x0a)を返して来て 1byteずれる... Orz

お〜ぃ、動いてるのは unix上だぞ!Windowsじゃないぞ

個人的には、MacOSX用の Intel Fortranでの動作が気になるところ(まさか、CR読むと CR+LFを返して来るのでは...)

なんらかのコンパイルオプションかディレクティブで制御できるのかな?

(2008/02/28追記)

テストベクタと Read[]の戻り値の読み違えですた

正しくは、「CR(0x0d)+LF(0x0a)を FGETCで読むと LF(0x0a)だけが 返ってくる」です。

どちらにしろ、uni-byte streamを読みたくてFGETCを使っているのだから、 勝手に改行記号の変換してくれるのは迷惑以上の何者でもない...Orz


2008-02-23 [長年日記]

_ [SAD]RCSタグ邪魔

SADのコードには、Header RCSタグを含むものが有るのですが、 diffやマージ作業の邪魔以外の何者でも無いような...

タグに含まれる最終変更日と最終変更者は、repositoryに聞けば 判ることだし、RCS由来でパス名がレポジトリサーバー内での 絶対パスなのはいただけない。おかげで、mirror pserverと master repositoryから取得した working copyの diffを 取ると悲惨なことに Orz (master repositoryが VPN経由でしか参照出来ない& VPN使うと全てのパケットが VPN Gateway経由になるので、 commit時以外は mirror pserver使わないと不便なんですよね)

Subversionでは、この辺りの基本情報はsvn infoで オフラインからでも見れるのがありがたい (checkoutした revisionに対する diffrevert操作も オフラインできる)

もっとも、working copyに checkout revisionのオリジナルが まるごと保管されているので、disk spaceは CVSの2倍消費しますが(w


2008-02-24 [長年日記]

_ [FreeBSD]どうやら、7.0-RELEASE build開始らしい

RELENG_7_0_0_RELEASE tag出現、どうやら2月末ぎりぎりリリースのようだ。 まあ、それなりに安定してるけど、一部の portsは依然として動かないので要注意 (devel/valgridとか)

RELENG_7では、editors/openoffice.org-2がコンパイルできん... Orz


2008-02-26 [長年日記]

_ [SAD]sad+修正

GCC 4.3.0だとコンパイルエラーが出るのでいろいろ修正

signed intと unsigned intの比較で警告が出てるとか、 2次元配列の初期化子が一次元配列で警告出まくりとかは 可愛いものですが...

外部結合な関数を参照するのに classスコープ上で friend付きで関数を宣言しているのが、 GCC 4.3.0にそんなシンボルは名前空間が無いよと言われる。 確かに、classネームスコープには居ない関数だよね。

というか、組み込み型を引数に取って内部でも組み込み型の大域変数にしか 触らない関数はclass memberにアクセスしないのでfriend宣言は要らないと 思うのだが...なんで付いてるんだろう?

教えて、えらい人

どんな言語でもそうだけど、頼むから言語規格に目を通してから コードを書いてくれ Orz

_ [tDiary]XMLエラー

XMLエラーが出たので、MathWikiスタイルで書いた日記の\$の エスケープをごそごそ直したが(確かに抜けが有ったのだが)、 昔問題なく表示していたページもおかしくなっている...

tdiary-replaceかけまくってから気がついたが、 x-mathプラグインのアップデートによるcache形式の変更で cacheが腐ったようだ...早く気づけよ Orz


2008-02-27 [長年日記]

_ [SAD][Fortran]Q編集記述子

Q編集記述子は、すでに調べた通りベンダー拡張なので 使うべきでは有りません。read文に置いては、Q編集記述子が 表れた時点でバッファ無いに有る文字数を返すので(Q,A)と 書けば、読み込んだ文字列の長さが判るわけです。 Fortranの文字列仕様(変数のサイズは固定でも中身のサイズが判らない)で パーサー書くには必須とも言える機能なので、新しいFortranには 同等の機能が無いはずは無いと思うのですが...やはり有りました(w

Fortran90の停留入出力での入力で、

integer :: nc
character(len=256) :: s
read(lfno, fmt='(A256)', advance='no', size=nc) s

という構文が使えます。ここでは、 sは長さ256の文字列バッファに 入力lfnoから改行・ファイル終端が来るか最大256文字読み込むまで 読み込み、読み込んだ文字数を ncに格納します。 停留入力なので、改行が来る前に書式指定の終端に達した場合は、 ファイルポインタはそこで停止します。 つまり、入力を1文字づつ読み込むことも可能です。

これ自身は、Fortran90規格に有るので g95でも使えるのが味噌

ただし、改行は特別扱いなので unibyte-stream入力には 厳しいですね。もちろん、改行記号特定1-character のみな処理系なら改行を検知したところで、バッファに自前で 改行記号を送り込めば良いわけですが、移植性がありませんね (改行記号が1-characterでもCRかLFかそれ以外かは環境依存)

実際、Fortran I/O libraryが気を利かせている実装の場合、unix上でも CR-LFのシーケンスを改行記号に扱ったり(例えばg95/gfortran)、 単独のCRに対して次のLFを読みにいってCR+LFで無い場合は 改行記号扱いし次の一文字は読み飛ばしたままだったり(例えばgfortran) するのでunibyte-stream入力を停留入力で扱うのは難しそうです。


2008-02-28 [長年日記]

_ [SAD][Fortran]Fortran I/Oの怪

Fortran90から入った停留入力で制御文字"\\r"の振るまい奇妙なので、 実装ごとの挙動を調べてみました。

ここでは、"\\r","\\n","\\r\\n"などの改行記号が 入力列に含まれて際の read文からの戻り値を調べています。 サンプルとした入力列は、"abc\\rdef\\n\\nABCDEF\\r\\n123456\\neof"です。 この入力列は、標準入力(UNIT=5)とファイル経由(UNIT=10)で テストプログラムに入力され、read文で停留入力による読み取りが行われます。

g95 0.91 20080220の場合

標準入力"abc\\rdef",size=7,iostat=-2"",size=0,iostat=-2"ABCDEF",size=6,iostat=-2"123456",size=6,iostat=-2"eof",size=3,iostat=-2
ファイル"abc\\rdef",size=7,iostat=-2"",size=0,iostat=-2"ABCDEF",size=6,iostat=-2"123456",size=6,iostat=-2"eof",size=3,iostat=-2
  • 標準入力とファイル経由の結果は同じ
  • 単独の"\\r"は1文字として扱う
  • "\\r\\n"と"\\n"は改行記号扱いで区別できない
  • 複数文字を受け取る場合、改行記号とEOFを区別できない
    • 1文字づつ受け取る場合は、EOFを検知する直前が改行記号で無い場合には、size=0,iostat=-2が返って来る
    • この例だと、"e",size=1,iostat=0->"o",size=1,iostat=0->"f",size=1,iostat=0->size=0,iostat=-2->EOF検知

gfortran 4.2.4 20080220 (prerelease)の場合

標準入力"abc",size=3,iostat=-2"ef",size=2,iostat=-2"",size=0,iostat=-2"ABCDEF",size=6,iostat=-2"123456",size=6,iostat=-2"eof",size=3,iostat=-2
ファイル"abc",size=3,iostat=-2"def",size=3,iostat=-2"",size=0,iostat=-2"ABCDEF",size=6,iostat=-2"123456",size=6,iostat=-2"eof",size=3,iostat=-2
  • 標準入力からだと"\\r"の次が"\\n"以外の文字の場合に欠落する
    • CR-LFを仮定して LFを先読みした後に seekで戻しているが、un-seek-ableなストリームではこの実装はうまく動かない
  • "\\r\\n"、"\\r"と"\\n"は改行記号扱いで区別できない
  • 複数文字を受け取る場合、改行記号とEOFを区別できない
    • 1文字づつ受け取る場合は、改行記号とEOFを区別できる
    • この例だと、"e",size=1,iostat=0->"o",size=1,iostat=0->"f",size=1,iostat=0->EOF検知

gfortran 4.3.0 20080221 (prerelease)の場合

標準入力"abc",size=3,iostat=-2"ef",size=2,iostat=-2"",size=0,iostat=-2"ABCDEF",size=6,iostat=-2"123456",size=6,iostat=-2"eof",size=3,iostat=-2
ファイル"abc",size=3,iostat=-2"def",size=3,iostat=-2"",size=0,iostat=-2"ABCDEF",size=6,iostat=-2"123456",size=6,iostat=-2"eof",size=3,iostat=-2
  • 標準入力からだと"\\r"の次が"\\n"以外の文字の場合に欠落する
    • CR-LFを仮定して LFを先読みした後に seekで戻しているが、un-seek-ableなストリームではこの実装はうまく動かない
  • "\\r\\n"、"\\r"と"\\n"は改行記号扱いで区別できない
  • 複数文字を受け取る場合、改行記号とEOFを区別できない
    • 1文字づつ受け取る場合は、改行記号とEOFを区別できる
    • この例だと、"e",size=1,iostat=0->"o",size=1,iostat=0->"f",size=1,iostat=0->EOF検知
  • gfortran 4.2.4 20080220 (prerelease)と同じ動作

Intel Fortran Compiler Version 8.1の場合

標準入力"abc\\rdef",size=7,iostat=-2"",size=0,iostat=-2"ABCDEF",size=6,iostat=-2"123456",size=6,iostat=-2"eof",size=3,iostat=-2
ファイル"abc\\rdef",size=7,iostat=-2"",size=0,iostat=-2"ABCDEF",size=6,iostat=-2"123456",size=6,iostat=-2"eof",size=3,iostat=-2
  • 標準入力とファイル経由の結果は同じ
  • 単独の"\\r"は1文字として扱う
  • "\\r\\n"と"\\n"は改行記号扱いで区別できない
  • 複数文字を受け取る場合、改行記号とEOFを区別できない
    • 1文字づつ受け取る場合は、EOFを検知する直前が改行記号で無い場合には、size=0,iostat=-2が返って来る
    • この例だと、"e",size=1,iostat=0->"o",size=1,iostat=0->"f",size=1,iostat=0->size=0,iostat=-2->EOF検知

まとめ

  • "\\r\\n"と"\\n"が同一視されている
  • 2008/02/20頃のgfortran 4.2.4/4.3.0実装は明らかにおかしい
    • 先行するCRに対応するLFを一文字読み込みして探すのは良いとして、LFで無かった際に正しくストリームを巻戻せず入力を失っている(標準入力)
  • 改行記号終端でない入力でのEOF検知の挙動が実装で異なる
    • 改行記号によるレコード終端の取り扱いに差か?
    • gfortranは、EOFによる暗黙のレコード終端よりEOF検知が優先している
    • intel fortran/g95は、EOFによる暗黙のレコード終端によって一度、size=0,iostat=-2(改行〜レコード終端)を返してから、EOFを検知する

つまり、改行区切りなテキスト読み込み(itfgetbuf_)には使えるが、uni-byte stream入力には使えないと言うこと

性能比較

itfgetbuf_の実装を

  • Q editing
  • FGETC intrinsic
  • Fortran90 停留入力
  • read(2) system call

で行ったものを比較すると、read(2)が断トツに遅いのは予定通りだとしても、 停留入力がFGETCより遅いのは納得がいかないな

Intel Fortran 8.1で試すと、処理時間比は Q editing:FGETC:停留入力:read(2)で1:1.7:7:23ぐらいで、 FGETCに比べるて停留入力が4倍近く遅い... Orz

gfortranだと、FGETC:停留入力:read(2)で 1:1.6:8.9ぐらいでそれほど激しい差では無いですが停留入力の方が遅い

内容的には、I/O library側でループを組める&最適化できるので FGETCのループより早くてもよさそうなモノですが...

itfgetbuf_の実装に限れば、

  1. Q編集記述子が有るならそれを使え
  2. さもなくば、FGETC intrinsicを使え
  3. 他に手が無ければ停留入力で書け
  4. read(2)は最後の武器だ

ということですね。 実際は、binary Read[]で FGETC intrinsicが使われているので FGETCが未実装の場合、整合性を取ろうとするとread(2)で 全部実装するしかないのですが... (それでも、Write[]とFileSeek[]との完全には整合性しない)


カテゴリー: Admin | Emacs | EPICS | Fortran | FreeBSD | GCC | hgsubversion | IPv6 | KEKB | LHC | Lisp | LLVM | MADX | Ryzen | SAD | samba | tDiary | unix | WWW | YaSAI | お仕事 | イベント | 出張 | 宴会 | 数学 | 艦これ | 買いもの | 追記 | 雑記