まーにゃ@エンタメ系火事場エンジニアの日々

数々の「火だるまプロジェクト」を安請け合いし何度でも復活する 「自称・不死身のエンジニア」の物欲まみれの日々をつづる

【人生編】「2023-10-05@C言語&GOI環境」と「EWSと20冊英文バインダ」と私

「2023-10-05@C言語GUI環境」と「EWSと20冊英文バインダ」と私
と題しまして、小話を1つ。
EWS(Engineering Work Station)、
1995年にWindows95が発売され、「INTEL INSIDE」キャンペーンが
始まるまでの10年間
PC98なんぞ、足元にも及ばない、すんごいスピードとすんごい値段で
売られていた大企業の研究部門、大学の研究室向けのコンピュータの総称?です。
OSにはいま、はやりのiOS,LIUX,ANDROIND
の先祖であるUNIXが動いていました。
ーーーーーーーーーーーーーーーー
(1)iOS    (UNIXライク。カーネギーメロン大学の先生が作った
       UNIX互換マイクロカーネルーOS:Machが始まり。
       最近、どーなっているのか?不明)
(2)LINUX(大学生だったLINUSが、MINIXを見本にして、UNIXと互換をもつ機能を
      パソコン0から実装し、オープンソースとして公開。
      そのあと、オープンソースブームに乗って一大勢力に。)
(3)ANDROIDANDROIDスマホのほぼ標準となるOSは、
      LINUXベースだが、グラフィックスがスマホ仕様、
      長時間のバッテリー駆動と、必要ときの応答性(瞬発力)を
      両立させるためにポケットに入れているときは、
      使わないCPUの電源を落とし、
      {高速コア、高効率コア、待機時担当の高効率コア}
      など、多種多様なCPUの混載状態に対して
      バランスよく、タスクをを割り振るため、タスクスケジューラが
      とっても苦労してる印象。)
MINIX(オランダの某大学のアーノルド・タンネンバウム教授が
      学生のOS教育用の教材としてUNIXを見本につくったらしいOS?)
ーーーーーーーーーーーーーーーー
まあ、どーでもいいことですが・・
SES業界の一般用語にうといのでスキルシートがうまく書けません
これも、まあ、どーでもいいことですが・・
私の持つ、OSと、C言語のスキルについて
ちょっとまとめてみますね。
<(1)C言語以外のスキル習得>
C言語だけだと、食っていけないので、
PythonJAVA,JAVAScriptなど他の言語もお勉強してみました。
(実務経験は、残念ながら。。ありません。)
C言語以外のお勉強の方法>
(1)C言語で作りたいアプリ(マルチスレッドCPUの負荷モニタ)
   を作成する。
(2)それをベースに他の言語に移植
(同じ画面、動きになるように他の言語で書き直す)
という手段を使って、他の言語へのとっかかりは、学習できました。
(とっかかりのおまじないを知っておくのは自分的には、
 結構重要だと思っています。LOGICを書く以前にコンパイルエラーで
 止められると、そこでOUT! となるので、オブジェクト指向以前に
 まず、コンパイルできるコードを書く土台にのることが先決と考えました。)
その過程もBLOGに乗せてますのでご確認ください。
http://maasan-yuttari-nikki.seesaa.net/article/477894785.html
※以下は12CPU24スレッドのRYZENで動かしたものです。
マルチCPUの負荷をリアルタイムで表示させるソフトの開発.png

<(2)OSのスキル>
UNIX(SystemV)
ー>某電気メーカ入社時からWindows95が発売となる1995年まで
ー>6年程使用しておりました。
ー>自社製のEWS(エンジニアリング・ワークステーション)事業
ー>として「一人一台のワークステーション」をモットーに
ー>MAIL作成、報告書作成、プログラム開発まで
ー>仕事は、すべてこれでやってました。
ー>1995年以降、INTELのCPUがワークステーションよりも
ー>性能が上回ってしまったため
ー>ワークステーション事業撤退となりました。
ー>UNIXとは、一旦その時点で縁が切れました。

Windows95
ー>1995年以降、ワークステーションに代わり
ー>MAIL、報告書作成、PG作成まで使い倒してました。
ー>新規事業開発の画像処理テーマでは、
ー>当時まだ、動作不安定なWindows95
ー>画像処理のトレーニングはさせられず
ー>たまたま部署の片隅に余っていた
ー>SUNワークステーションを借りて
ー>1W昼夜問わず連続してプログラムを走らせ
ー>画像処理の認識精度改善の対策をとりました。
WindowsXP
ー>2000年以降は、Windows95に変わって
ー>MAIL,.報告書、PGのお供です。
ー>エンタメ機器のOSにも使っていました。

<(3)言語のスキル>
(2-1)C言語は、大学院の研究(2年間)で覚えました。
   幸いなことに
   多勢を占めたPC-98は先輩が研究で「がじがじ」使っていて
   空いていない。
   教授が「XX君、こんなものを”だまして”借りてきた
   君がUNIXとやらをマスターして広めるのだ」
   |-SUN-3ワークステーション
   |ー英文のバインダー20冊
   をどーーんと、渡され、UNIXマシンのお守りをするはめ
   なりました。

<大学院で習得したスキル>
(2-1-1)CPUが違う環境(マルチプラットフォーム)の
       データ変換方法
   研究はINTEL製CPUが入っているPC98が主体
   渡されたSUN-3は今はつぶれたモトローラ68000という
   CPU、データの並びがバイト単位で逆転。
   ワークステーション側で処理するには、
   データ変換(ビッグエンディアン⇒リトルエンディアン)
   が必要となります。
   データ構造の違いを意識させず処理することが求められました。
   (この知識は、あとあと、大手電気メーカで画像処理研究の際に
    余っているワークステーションを使う時に活用できました。)
 (2-1-2)GUIとイベント駆動型プログラミング
    SUN-3ワークステーションには、PC-98の3倍ぐらい
    デカいモニターがついてきました。
    システムを起動すると、いろいろ、画面に広げて操作できる
    マルチウインドウ処理ができることがわかりました。
    GUIを駆使したプログラムを作るには、
    イベント駆動型プログラミングが必要ですが、
    慣れれば、簡単、そこも何とか、クリアーし、
    先輩が作るFORTRANで書かれたプログラムに対して
    最下層のI/O処理をC言語で肩代わりさせ
    GUI操作型に変更して
    過去の資産を再利用して使えるような環境を作りました。
    SUN-3はワークステーション自身の出来も秀逸でしたが
    SUN-OS(BSDベース)が提供する機能
    特に、ソフトウェアをGUIを駆使してデバッグできる
    DBXというデバッガは強力で助っ人になってくれました。
    (SUNマイクロ自体は、そのあと、データベースメーカの
    オラクルに買収され、OSは、Solarisと名前を変えてますが
    DBXは、まだ、搭載されてると思います。)
    1987年(WInddws95発売の8年前)時点では、
    PC98よりSUN-3ワークステーションが圧倒的に速かったです。

(2-2)入社した電気メーカでは「一人一台」ワークステーション
    CAD関連の開発に従事した5年間は、開発から日常業務まで
    すべて、ワークステーションで行いました。
    UNIX+マルチウインドウの環境は変わらないのですが
    デバッガが「ADB」というCUIベースのゴミみたいなデバッガで
    「キレるほど使い勝手が悪い」ため、PGのコード内にprintf文を
    叩き込む。
    せっかく、XwindowというWindowシステムがありながら
    GUIデバッグできないオソロシイ効率の悪さ。
    大学時代のSUN-OS+DBXデバッガの方がソフト開発環境は恵まれていたと思います。
    この会社のUNIXに対してのノウハウは、微妙だと思いました。
    (SUNマイクロシステムズが当時、最先端であったこと改めて思い知りました。)
    (A)原始時代的なprintfデバッグ:printf(~,__FILE__,__LINE__);
    __FILE__,__LINE___と記載すれば、どこのファイルのどの行か特定できます。
    (B)assert()関数を使う。この場面でこの変数がこの数値でなければおかしい
    場合、assert()関数を使えば、「assertion failed」で止まります。    
    ゴミ箱に捨てたいほどひどいデバッガADBと、厳しい納期、ひどい上司が重なり
    つらい時期もありましたが、
    大学時代の研究室は昼夜もない・土日もない「研究は死ぬ気やらないと成果はでない」
 「はぁーー、昼夜もない、土日もねーー。死ぬ気でやらねば、成果もでねーー。。
  こんなラボいやだぁ。。こんなラボいやだぁ・・東京さでるべぇ」
  吉幾三ではございませんが。。
  教授のオーラに魅惑され自ら選んだ道ではありましたが、
  SUN-3だけが唯一の友達であった私には、
  会社が「え?土日休み?、お金がもらえる?」天国に見えました。
(2-3)新規事業開発センター画像処理課
    (2-3-1)顔画像認識(テンプレートマッチング)
    テンプレートマッチングという一般的な技術を使用して
    顔画像の特徴点{眉*2、目*2、鼻、口}の端点座標を検出します。
    検出精度を上げるには、出来のいいテンプレート画像を餞別する処理が
    必要となります。200人余りの人画像から、テンプレートの候補画像
    ならびにそのテンプレート画像に含まれる、特徴点座標(検出正解座標)
    を人海戦術で、抽出し、200人分のテンプレート候補画像を使って
    200名のテンプレートマッチング処理をさせ、結果座標と正解座標の
    差分が最小となるものがいちばん成績の良いテンプレート画像
    (ゲーム機に組み込みできるテンプレート画像となります。)
    200テンプレート候補X200人物画像X6カ所の顔部位
    =24万回の処理をワークステーションにやらせますと
    24時間X7日=168時間かかりましたが、やりきらせました。

    (2-3-2)似顔絵処理のI/Oの高速化
    エンタメへのとっかかりは、センター長が
    「似顔絵を使ったゲーム機でわが社の技術力を世間に知らしめる」
    と勝手に暴走し、500台分(約5億円)の費用を協力会社に
    払ってしまったのが事の発端です。
    (後々、不良在庫の2億円(200台)を0にせよ!と火だるまに。。)
    ゲーム機に求められるのは、応答性、お客さんを待たせると客の回転率が
    落ちるため、お店で売り上げが上がらず、店長に買ってもらえません。
    画像処理自体の、速度改善も必要ですが
    とにかく、かかえている1万を越えるファイルへのアクセス
    ファイルのOPEN。CLOSEが多量に発生すると足を引っ張ります。
    必殺技として、このOPEN.CLOSEのシステムコール
    1回で終わらせる。そのためには
    |-1万個のファイルをすべて連結して1つのデータベースにする
    |ー開発者にはファイルアクセスにはOPEN.CLOSEではなく
    |-XX_OPEN,XX_READ、XX_CLOSEを使ってくれ、
    |ーXX_OPENの中では開発モード、リリースモードを有し
    |ーINIファイルのフラグを立てれば、切り替えられる
    |ー開発中は、開発モードで、各ファイルにアクセス。
    |ーPG変更禁止、テストフェーズに入ったら
    |ーINIファイルをいじって、リリースモードに切り替えます。
    |ーXX_OPENは1回CALLされた時点で
    | データベースファイルをOPENし、
    | 相対パスで指定されたファイル名文字列を2分木探索で
    | 下記のデータベースのヘッダから検索、
    | 得られたデータ定義位置までFSEEKシステムCALLで移動
    |ーXX_READシステムCALLで目的のデータを読み込む。
    |
    |<エンタメ機器組み読み用のデータベースの構造>
    | |  
    | |<ヘッダー情報格納部@1万ファイル分>
    | ||ーファイル名文字列を相対バスで記憶するエリア
    | ||ーファイル名に対応して実データが存在するデータ格納部の位置
    | || 実データの読み込むデータサイズ
    | |<データ格納部@1万ファイル分>
    | ||ーファイル名に対応したデータを(TEXT,バイナリ画像)
    | ||  すべて連結して格納しているデータエリア
    |
    | 次にXX_OPENがCALLされたときは
    | FTELLで現在のSEEKポイントがファイル内のどの位置にあるか
    | 把握し、ヘッダから得られる、データ定義場所との差分から
    | FSEEKでファイルポインタを「相対移動」させ、
    | 目的のデータをGETできるようにしました。
    | ★成果★
    | 一万を超えるファイルアクセスにかかる時間コストを削減し
    | ファイルI/Oにかかる時間を50%以上削減
    | ゲーム機への搭載で問題ない速度を達成できました。

(2-4)直近9月の出来事
    友達が社長をやっているソフトハウスからの相談うけました。
    <目的>
    「請求書」をSCANして必要な文字、数値情報を電子化したい。
    <やったこと>
    この手の話は、はやりなので、先行事例調査で
    「請求書 画像認識」といったキーワードで
    大手メーカがたくさんやっていること、アマチュアが挑戦していること
    ネタは調べ放題です。
    <制約条件>
    ・画像の品質(曲がった画像、汚れた画像、色々な角度の画像)
     を認識して品質を一定化すること。
    <リスク要因>
    ・請求書の書式の種類が膨大であること。
    <先行事例を調べて判明したこと>
    ・老舗の事務機メーカは、優秀なデータサイエンティストを雇って
     ディープラーニング技術を使っていること。
    ・画像処理で100点はとれないので、
     |(A)画像から文章の構造を解析分類する処理
     |  |ー画像の解像度を意図的に落とす(セグメンテーション技術)
     |  |ー解像度どんどん落としていけば、文字の密度の傾向、四角は表みたいに
     |  | 請求書の伝票の構造的特徴がざっくり「漢字」的イメージで把握できます。
     |  |ー分類用テンプレート画像を準備してテンプレートマッチング技術で
     |  | マッチングさせると、おおよその分類はできる(100点はとれない)
     |  |ーここで、どのテンプレートにも当てはまらないものは、エラーではねます。
     |  | 「すみません!認識できません。申し訳ない! 手で入力してください」
     |  
     |(B)分類後の画像に対して、画像が持つ、伝票の特徴
     |   請求書の書式に従って関連付けて抽出する処理
     |  |ex)請求書という文字が来たら、その下側の伝票画像の幅の50%以降~最後
     |  |までの間には、会社名、住所、電話番号、銀行振込先が記載されている。
     |  |そこをすぎてY軸をSCANすると、表にぶち当たり、表は罫線で囲まれ
     |  |項目名を定義した行、数値を定義した行で構成される。
     |  |画像を白黒化して、”白”、”白じゃない”の境目から罫線を検出
     |  |検出した罫線のY軸下方向には、項目名文字列があるので、罫線の境目を
     |  |判定し、文字列画像を切り出す。
     |  |更に画像処理で文字列画像を1つの文字に切り刻んだ文字画像にして
     |  |ライブラリ関数の 文字画像ー>CHAR変換をかける。
     |  |最終的には、{項目文字列、対応した項目数値}をGETできます。
     |  |★一つの請求書で、これだけ手間がかかります。★
     |
     |(C)”(A)”、”(B)”の処理結果が信頼できるものか
     |   信頼性を評価して
     |   |ー1)読み取ったデータの信頼性に自信があるのでそのまま使え
     |   |ー2)信頼性が微妙なので人間が介入してダブルチェックしてくれ
     |   |ー3)認識エラーなので 人間が伝票を見て 入力してくれ

     といった処理がされていました。
    ・大手さんでさえも、これだけ大掛かりなシステムを組んでなお
     救えないデータが残る画像処理の世界はオソロシイ。

    ・処理の流れは問題を細かく砕き、分類した問題に対して解決策を打つのが鉄則
    ・(C)はできなくても(A)、(B)はできるかもしれないが
     請求書の種類はオソロシイ数ある。みつかるたびに(A)、(B)の
     処理を増やしていく、いちいち、請求書の書式の特徴を「うーん」と唸って
     目を皿のようにして、全体を見渡し、LOGICアイデアをひねり出す。
     1伝票のLOGICアイデアを出すのに1日じゃとてもできないし。。
     これは、終わらない「地獄絵巻」の世界になる。
     画像処理は100点がとれない世界。エラー処理どーする?

     売ったら売ったでカスタマーサポートの責任も発生する。
     10回エラー出たら、「金返せ」と訴えられる。
     上記の内容と調べた範囲のサイトの資料を報告書としてまとめ、

     ★結論★)自作で「請求書認識処理」PGは地獄直行となる。
       市販で安いソフトがあるなら責任持たなくて済むので
       そのソフトを自腹で購入して使い倒し、
       できること/できないこと をハッキリ把握・理解した上で
       運用のストーリを企画書にまとめて、
       クライアントさんとすり合わせしないと、死ぬよ!
       画像処理はとにかく手間の割に報われない。地獄を見たいか?
       ちょこちょこっとネットワークでSQLサーバーと接続して
       データをやり取るするのとはレベルが違う。
       WEB->サーバーのDBで、接続が100%保証できないなんて
       ありえないだろ?画像処理は100%が保証できない
       そういう世界なんだよ。。
      と お伝えしておきました。
脈略もなく書いてしまいましたが、
まあ、こんなもんです。
<★2023年時点でC言語に対して思うこと>
(1)使える部品は、使わせていただく。
0からアルゴリズムを書く前に、フリーのライブラリを探してみましょう。
インターネット経由で、フリーのライブラリや、LOGICのソースコード
オープンに配布されている場合があるので、その部品を使わせてもらいましょう。
ー>画像処理ならば、OpenCVなどのライブラリがあります。
ー>C言語ライブラリをオープンソースで公開みたいなサイトもあります。
(2)他人のソースコードを積極的に読んでみる。
技術力があり、丁寧な仕事ができる方のソースコードを見せてもらう。
ー>ちゃんとコメント付きで、
ー>課題に対してどのようなアプローチで解決しているのか
ー>新しい知識、アイデア、発想を身に着けることができそうです。
ー>自分の場合、他人のコードを読む時間をうまく捻出できなかったのは
ー>非常にもったいないことをしたと反省しています。
(3)インターネットにある興味がある分野のソースコードを読む。
”(2)”がなければ、インターネットに上がっているコードを読む。
ー>例えば、エミュレータが好きならPCSX2(プレステ2エミュレータ
ー>Dorphin(Wiiエミュレータ)などのコードを読む。
ー>好きなら、ソースコードを読むことも苦にならないと思います。
ー>GUIまわりから手を付けて、I/Oまわり、メモリー管理回りのソースを
ー>読むことで、いいアイデアが、得られるかもしれません。
ー>LINUXカーネルソースコードだって、見れますし、
ー>カーネルソースコードを解説しているサイトもあると思います。知らんけど。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
C言語の高速化には、現状を正確に把握して、「遅い」という問題解決のため
足を引っ張っている容疑者を早々に見つけ出し、
時間的余裕があれば、根本対策を打ち。
余裕がなければ、暫定対策で手打ちにするなど柔軟な対策を打つことです。
<現状把握>
・プロファイラというツールを使えば、処理のボトルネック
 (時間を奪っている重い処理の関数、呼び出し回数が多い関数など)
 がわかる(はず)ので
 時間がかかっている原因となる関数
 |-処理時間かかる関数ー>処理LOGICの見直し
 |ーたくさんCALLされている関数
 | ー>マクロにする(ソースコードがINLINE展開され関数呼び出しのコストを
 |   1つ減らすことができる。)
 | ー>CALL回数を減らすため、上位のLOGIC見直しを検討する。
<次の打ち手1>
・時間のかかっている関数内の処理LOGICの見直し
 |ーどうでもいい無駄な処理が入ってないか??
 |
 |ーそもそもアルゴリズムをミスってないか?
 | 検索をforループとif分でやるのは×、2分木探索などを使用すべき。
 |
 |ー今やるべき処理なのか?
 | あとでまとめてやってもいいのでは?
   (処理をできるだけ先送り、まとめてできないか?)
<次の打ち手2>
・できるだけOSのシステムCALLを使用する回数を減らす。
ー>浮動小数点を使う演算も時間がかかります。(2023/10/09#追加)
ー>例えば、三角関数(SIN,COS)を使う座標変換などで
ー>ライブラリを作るといった場合、そのライブラリの使われ方を
ー>事前にヒアリングしておくといいと思います。
ー>その処理の使われ方が、
ー>45度、90度、135度、180度、225度、270度
ー>といったケースが多く、変な角度の指定がない場合は、
ー>あらかじめ、計算した数値を準備し、座標変換に三角関数を使わない
ー>単なる乗算処理にし、上記以外の角度指定があった場合だけ、
ー>三角関数を使うことで、三角関数を使わず
ー>単なる乗算だけにすることで時間コストを
ー>下げることができます。
ー>角度として1度未満の精度が要求されない場合は、360度分の
ー>SINの計算結果を定数配列にあらかじめぶち込んでそこを参照させれば
ー>COSはSINの90度からスタートなので、三角関数は配列参照に置き換え可能
ー>CPUにとってはパイプラインを乱す、条件判断文も不要となるため高速化できる可能性があります。
ー>このように処理が具体的にどのように使われるケースが多いのか、要求される精度などを鑑みて、
ー>コードを簡略化するという作戦も取れます。
ー>ファイルI/Oに対しては、CALL回数を減らす工夫をすることで
ー>かなりの速度UPが期待できます。
<次の打ち手3:ちょっと難しい>
・メモリー管理malloc.freeもOSのシステムCALLなのでコストがかかります。
 あらかじめ、大きな固定配列を宣言し、
 システムCALLを真似た関数XX_malloc()でその配列から
 必要分のメモリーアドレスを渡す。XX_free()がCALLされたら、
 配列内部でうまく、データエリアのやりくりをする。
 (NETで調べると、自前でメモリ管理する事例もGETできるかもしれません。)
C言語をがりがりに、やっておられる方や、
組み込み分野でコンパクトなコードを常に意識してコーディング
されている方から見たら、
基本動作以下のレベルの低い話かもしれません。。。
ちょっとだけでも 参考になると 幸いです。
では・・また・・:_;)/