StudyCS.log

ただの日記

学部1年前期をふりかえる。

<<前 ないよ

>>次 学部1年後期を振り返る

 学部1年生の前期課程が修了したので、取り組んだことや感想、環境や考えの変化を、自分のtwitterの投稿を見つつ振り返りたいと思う。本当に個人的な日記。

TOEICの勉強から始まったキャンパスライフ

  大学の合格発表と同時に、TOEIC実施のお知らせを受けた。このため大学が始めるまでの春休み期間はTOEICの対策に費やされた。しかしコロナの影響もあり、試験はいまだに実施されていない。

 対策の内容としては、単語帳の周回と公式問題集での練習くらい。

 3月の初旬から始めて、4月の終わりには10周を達成した。5月の初旬くらいはリスニングの対策をしていた。

 このようにしてCS学科の学部生としての始まりはTOEIC対策からであった。

業界研究を始めた。

 これについては少し意見が変わったかもしれない。ただ入学当初は、学部4年間を終えたら即就職するつもりでいた。(当時は、進学はモラトリアムの延長に過ぎないと考えていたので)そのため、業界研究は入学した4月から始めている。

 最近では、業界研究を進めたり、前期のカリキュラムをこなしてみて、本気でCSに取り組もうと思ったらやはり学部4年間では足りないかな、と思い始めた。

 どの業界に入るかというよりは、まず進学するのか就職するのかというレベルでまだまだ悩んでおり、進路については今後もしばらくは流動的である。

一人暮らしを始めた。

  大学に入って、実家からは少し距離があるところに来たので一人暮らしを始めた。僕自身あまり家事の手伝いを積極的にやるというタイプでもなかったので、どのように生活していくか本当に試行錯誤(行き当たりばったりと表現したほうが適当か)であった。

 今となっては、もう一人暮らしが快適すぎて実家暮らしには戻れないが。

CSを学ぶコースでCSを勉強する時間がないという謎シチュ

 大学では学部1,2年の間は一般教養科目の単位をそこそこの数取らなければならない。それも、ただ単位を取ればよいという話ではなくて単位に付随する成績評価の平均値、GPAを極力高く保つ必要がある。

 履修したからには良い成績で単位を取りたいというのは当然の感情であるが、それをするには大量の時間をレポート作成に投下する必要がある。

取った講義にもよるが、大学の課題も決して少なくはないので真面目に取り組めば取り組むほどCSの勉強に使える時間が無くなるという、つらい状況にしばしば陥った。

 後期はもう少し慎重に一般教養科目を選ぼうと思う。

今なおクラスメートの顔と名前が一致してない

 今年は、間違いなく歴史的な年として今後語られていくに違いない。あまり良い意味ではないが。COVID-19の影響を受けて、ほとんどの講義はZoomによるオンライン授業、あるいはオンデマンド形式で行われた。

 そのため当然であるが、クラスメートとの横のつながりはほとんどなく、クラスメートの顔、名前、人柄が全く把握できていない。

 オンラインで実施可能という状況の中リスクを冒してまであえて対面の講義を開講する理由はない、という大学の言い分はよくわかるし、僕個人としては大学に特別何かしてほしいとも思っていない。しかし、多くの大学生にとってあまり楽しくない状況が続いていることは確かであろう。

コンピュータの使い方 → コンピュータそのもの に興味を持ち始めた

 大学入学当初、僕の主な関心ごとはコンピュータをいかにうまく使うか、であった。それに世間的にも日の光が当たるのはそういった事柄だろう。"いかに早いコードを書くか"、"どのようなソフトウェアを書くか"、"LinuxAWSなどの機能を業務レベルで使いこなせるか"etc ... 

 しかし、CSを学び始めてから読んだ書籍、主には、支える技術シリーズの「プロセッサを支える技術」や情報処理学会の「コンピュータアーキテクチャ」などの書籍の影響を受けて、だんだんとコンピュータそのものや、その設計に興味の対象が移っていった。

 大学のカリキュラムを見ると、学部の後半(3,4年)ではこういったことが主なテーマになってくるようなので、非常に楽しみであるし、将来的にもこういったコンピュータ自体のシステムにかかわるような仕事をしたいと思っている。

 

学部1年前期のまとめ

 ・コンピュータシステムに興味を持つようになった

 ・一般教養科目は慎重に選ばないと、自分が本当に勉強したいことをする時間が無くなる

 ・大学院への進学も視野に入れたほうが良いかも

 

 

 

 

 

そもそも浮動小数点数ってなんなのか

概要

 プログラミングの技術書を読んでいると、たびたび浮動小数点数という言葉が登場する。しかし、それに反して、浮動小数点そのものが何なのかについて踏み込んだ説明が少ないように思うので、書き残しておきたい。

動機

 プログラミングの講義で小数点以下の20桁を出力せよという課題が出され、double型(C言語における、浮動小数点の変数のための型)では、無理じゃね?と思い調べ始めたところ、そもそも浮動小数点の規格について理解が浅かったことを思い知らされた。そこで、これについて未来の自分のために書き残すことにする。

内容

 float,doubleは浮動小数点数を代入できる型です。と、多くの技術書には平然と書かれているが、そもそも浮動小数点とは何なのか。

浮動小数点数とは何なのか。

  浮動小数点数は、その名の通り、小数点が浮動している数のことである。対義語は固定小数点数。コンピュータは0,1,で数字を表現している。ここでそれが整数であれば、0,1の並びの1通りと、一つの整数を一対一対応させれば表現できるのだが (例えば00000001 → 1とか)、小数でそれをするのは非常に非効率である。整数と小数では表現しなければならないパターン数に点と地ほどの差があるからだ (ビット列を小数と一対一対応させてたらメモリがどんだけあっても足りない) 。

  そこで小数を符号、仮数、指数に分割してそれぞれ表現する方法が考え出された。

   {(符号)}{仮数 \times 2^{指数}} (2進数に変換後。IEEE754の定義は後に示す。)

  このように表せば、符号を表すビット列、仮数を表すビット列、指数を表すビット列と分けて表現することで、柔軟に小数を表現できるようになる。

  現代のコンピュータでよく使われている小数表現の規格「IEEE754」では、次のようなビット列で小数を表すことになっている。

  (* 説明書きをしているが、説明書きだけではイメージがつかみづらいと思う。下に例題を用意したので、説明を見ながら追ってみてほしい。)

  単精度(32 bit)

符号(1bit) 指数(8bit) 仮数(23bit)

  倍制度(64 bit)

符号(1bit) 指数(11bit) 仮数(52bit)

  4倍制度(128 bit)

符号(1bit) 指数(15bit) 仮数(112bit)

 

  符号をs,バイアス付き指数をe-bias,先行ビットをj,仮数部をfとすると、

  浮動小数点は次のように表現される。

  {(-1)}^s{2}^{(e-bias)} \times{j.f} 

            (oracle Cユーザーズガイドより抜粋)

 

 符号s-1 , +0と対応する。

 先行ビットjは常に1になるので基本的には省略される。しかし、アーキテクチャや型によっては、明示的に示すこともある。

 仮数fは2進数変換後に一番左が1になるまでシフト演算を行い、その仮数の小数点以下を仮数部に格納する。

 指数部に関して、バイアス付き指数ってなんなんだ、という話になると思う。これは指数部のeが符号なし整数であることに原因がある。だからバイアスをかけて、負の範囲も表現可能にしている。32bitの単精度では127、64bitの倍精度では1023がバイアスとなる。

例題 10進数小数を2進数に変換し、IEEE754規格に従ったビット列にしてみよう

 ここでは、10進数小数19.24(これを書いている現在時刻)を2進数小数に変換し、それをIEEE754に従ってビット列(64bit)にしてみよう。

 まずは、19.24を2進数に直す。すると           

   10011.00111101011100001010001111010111000010100011110101110000101・・

 となる。小数点を含む10->2進数変換について、この計算には終わりがない。整数の範囲であれば2進数でもうまく使えるのだが、小数点が登場すると正確に表すことが不可能になり、誤差が発生する。(2の累乗であらわされる数か、またはその部分和である場合においては例外) ただ、ここでは誤差の修正については触れず、とりあえず気にせず先に進むことにしよう。(なぜなら死ぬほど記事が長くなるから。)

  2進数が得られたら、仮数1.~~になるようにシフト演算する。

 {1.001100111101011100001010001111010111000010100011110101110000101}\times{2^{4}}

  出来たら、仮数部は完成したも同然なので先頭からどんどん格納していこう。前述のとおり、先頭ビットは省略されるから、仮数部は次のようになる。

12 13 14 15 16 17 18 19 20 21 22
0 0 1 1 0 0 1 1 1 1 0
23 24 25 26 27 28 29 30 31 32 33
1 0 1 1 1 0 0 0 0 1 0
34 35 36 37 38 39 40 41 42 43 44
1 0 0 0 1 1 1 1 0 1 0
45 46 47 48 49 50 51 52 53 54 55
1 1 1 0 0 0 0 1 0 1 0
56 57 58 59 60 61 62 63 64    
0 0 1 1 1 1 0 1 0    

 入りきらないものは切り捨てられる。悲しい。 

 続いて、指数部eを作っていこう。eは符号なし整数であるから、負の範囲を表現するにはbiasをかける必要がある。表現したい指数をOとすると、

   {O}  = {e-bias}

   \therefore {e} = {O+bias}

  今回のケースでは、 {O} = {4} , {bias} = {1023} だから、

   {e} = {4 + 1023}\\={1027}

  これを2進数に直して、指数部は

  10000000011

となる。

  格納していくと、

2 3 4 5 6 7 8 9 10 11
1 0 0 0 0 0 0 0 1 1

 

 最後に符号ビットを格納する。今回は正の数なので、0

1
0

よって、ビット列は

0100000000110110011110101110000101000111101011100001010001111010

となる。

double型の計算精度は何桁まで保たれるか

 この記事を書き始めた動機として、double型の仮数の計算精度がどの程度か示しておきたい、というのがあるので考えてみる。

 ありがちな近似として、 {2}^{10} = {10}^{3}というのがあるので、これを利用してみると、

    \frac{52}{10} \times 3 = {15.6}

よって、計算精度は15桁以上16桁未満の間で保たれることになる。

これに伴い、学校の演習課題で指示されたdouble型での小数点以下20桁出力はおそらく実現不可能であると考える。

まとめ

 浮動小数点形式は、小数点表示においてメモリを効率的に扱う表現法。

 64bitのdouble型では、仮数20桁の計算精度を保つことは不可能である。

プロセッサの性能評価方法まとめ

f:id:HoriK:20200902110853j:plain

プロセッサの性能を評価したい


概要

 適切なプロセッサを採用するためにはニーズに合わせて正しく性能を評価する必要がある。本記事では、プロセッサを評価する際に使われる一般的な評価基準をまとめている。

動機

 コンピュータアーキテクチャの本を読んで、評価基準をいろいろ知ったのでまとめたかった。

内容

 コンピュータの最も一般的で大きなくくりとしての評価基準は、コスパ性能消費電力が代表的。

 コスパ ->最も感覚的でわかりやすく、妥当な評価基準。コスパは高ければ高いほど良い。

 性能 ー>プロセッサの性能が高いのか低いのか。一般的には一定時間に処理される作業量であるスループットや、一つの作業にかかる時間である応答時間を見て評価する。これらを評価する評価基準はいくつか存在する。

 ・クロック周波数

   プロセッサは一定のクロックに同期して処理をしている。1クロックの時間をクロックサイクル時間と呼び、これをT(s)とすれば、クロック周波数F(Hz)はその逆数となる。

                                              { F(Hz) = \dfrac{1}{T(s)} }

 ・CPI (Clocks Per Instruction)

    命令実行に必要なクロックサイクル数の平均値。この値が小さいということはより少ないサイクル数で命令を実行できるということであるが、命令にかけるクロック数を減らすと命令数自体が増えるので、結局は命令数とトレードオフの関係にある。

    プログラムの実行時間が分かっていれば、CPIを計算することができる。

    プログラム実行時間をS(s) , 命令数を n(個) , クロック周波数をf(Hz) とすると

                                           {S = \dfrac{n・CPI}{f}}

             ここで、

                                           {S(測定可能) = \dfrac{n(測定可能)・CPI}{f(マシンの固有値)}}

   であるから、CPIについて解いて

            {CPI = \dfrac{f・S}{n}}

    で計算できる。

   上記の計算式より、CPUの性能向上にはクロック周波数fを上げる、CPIを下げる、命令数を減らす、などが考えられるが、CPIと命令数を同時に下げることは不可能なのでよい塩梅でそろえてやることが大切。

   なお、近年のマシン性能向上によりCPIは小さな値となってきており、比較用の値としてはわかりやすさに欠けるので、その逆数をとったIPC(Instructions Per Clock)が使われることもある。

           {IPC = \dfrac{1}{CPI}}

 

  MIPS

    1秒間当たりの命令実行数を百万単位(10^6)単位であらわしたもの。

            {MIPS = \dfrac{命令数}{実行時間\times10^6}}

              感覚的に理解しやすい指標ではあるが、実行するプログラムや最適化(例えば複数の命令を1サイクルにまとめるとか)の影響を受けやすい。そのためMIPS値の増加が、必ずしもプロセッサの性能の向上を表すとは限らない。また、そもそも命令セットが異なる場合には指標として使い物にならない。(命令数が大きく異なるため)

  ・MFLOPS

    1秒間当たりの浮動小数点演算の実行可能回数を100万単位で表したもの。スーパーコンピュータの性能比較にもたびたび利用される。プログラムを実行して測定された実測のMFLOPS値は実行性能と呼ばれる。また、100万単位で表すMFLOPSのほかに、10億単位で表すGFLOPS、1兆単位のTFLOPS、1000兆単位のPFLOPSなども使われることがある。

  

 消費電力 ->特に携帯電話やノートパソコンのように、電池持ちが重要なマシンではこの値も重要視される。加えて、一般に消費電力が増えると発熱量も増えるため、デスクトップ向けのプロセッサでも無視できない値である。

 コンピュータには動的な消費電力と静的な消費電力がある。前者はトランジスタのスイッチングに利用され、後者はCMOSゲートからリークする電力である。

 スイッチングに利用される動的な消費電力は、消費電力P、負荷容量C、電源電圧V、周波数f、出力がスイッチを伴う割合aを用いて一般に以下のように与えられる。

                    {P = \dfrac{C \times V^2\times a\times f}{2}}

    上記の式より、クロック周波数、電源電圧、スイッチの割合を減らすことで消費電力が減少することがわかる。

 

まとめ

 クロック周波数、CPI 、MIPS 、MFLOPSなどから性能が計算、比較できる。

 また、電圧やスイッチの変更割合、クロック周波数などが分かっていれば、そこから消費電力を計算することもできる。消費電力の低さから性能が比較できる。

 その他、コスパが比較要素として重要なのは言うまでもないだろう。