4/11 イントロダクション(Introduction) (1)
講師紹介
- 田中哲朗のWWWページ
- 普段の居場所は駒場情報教育棟3階 E33研究室
- メールでの質問は,
宛にメー
ルを出すこと.回答を全体で共有した方が良いと思わ
れる場合は,差出人を伏せた上で,教材に引用することがある.
成績評価
- レポート(6回程度予定)
- レポートの提出は,
ITC-LMS という学習支援システム
で行なう.教育用計算機システムのアカウントを使ってログインして,「コース検索」で
,「受講可能なコースのみ」を選んで「コース名」で「情報数理科学」で検索すると他の先生の講義と田中の「08D1304 情報数理科学II[広域システムコース]」がみつかるので,これを登録する.コース選択で,4つの選択肢から選ぶ必要があるが,「08D1202情報数理科学II[総合情報学コース]」を選ぶことを推奨する(違うコースを選んでも影響はすくないはず).
- 講義中に投票システムを使って投票をしてもらう.1回の講義中に1度でも投票すると出席点を加える.1回の講義の出席点は全体の評価の1/100以下とする
教科書
参考書/参考資料
- 石畑清: アルゴリズムとデータ構造, 岩波書店, ISBN 978-4000103435\\
アルゴリズムとデータ構造に関する教科書としては易しく読みやすく安い(3900円).内容がちょっと古めになっている.
- J. Kleinberg, E. Tardos著,浅野孝夫他訳: アルゴリズムデザイン, 共立出版, ISBN- 978-4320122178.
入門というよりは,上級者向けの内容.
授業日程
- 4/11
- イントロダクション(Introduction)(1)
- 4/18
- イントロダクション(Introduction)(2), 配列ベースのリスト(Array-Based Lists)(1)
- 4/25
- 配列ベースのリスト(Array-Based Lists)(2)
- 5/2
- 連結リスト(Linked Lists) (1)
- 5/9
- 連結リスト(Linked Lists) (2)
- 5/16
- スキップリスト(Skiplists)
- 5/23
- ハッシュテーブル(Hash Tables)
- 6/6
- 二分木(Binary Trees)
- 6/13
- 赤黒木(Red-Black Trees)
- 6/20 (集中講義に伴う休講)
- 6/27
- ヒープ(Heaps), ソートのアルゴリズム(Sorting Algorithms)
- 7/4 (海外出張と重なる可能性あり)
- その他
- 7/11 (栃木実習に伴う休講)
講義スライド
講義で使ったスライド(PDF形式)はITC-LMSで公開.
リンク集
演習(C++プログラムの速度計測)
この演習では,Mac OS上で行なう.Windows環境が得意な人は,そちらで
おこなっても良いが,サポートはしない(Visual C++よりも,cygwinのg++を
使った方がそのまま実施しやすいかもしれない).
以下の関数fは整数(int)を要素にするvectorにn回要素を追加(push_back)してn回要素を削除する何もしない関数(何もしないが,コンパイラの最適化で削除されることはないように工夫して
いる)である.
void f(std::vector<int> &v, int n){
for (int i = 0; i < n; i++) v.push_back(i);
for (int i = 0; i < n; i++) v.pop_back();
}
さまざまな,nを与えた時の実行時間を測るためのプログラム
vector_speed.cpp をコンパイル実行してみる.
なお,今後の演習では,ホームフォルダの下にmis2というフォルダを作って,
そこで作業することを前提とする.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
uint64_t cputime(){
unsigned int ax,dx;
asm volatile("rdtsc\nmovl %%eax,%0\nmovl %%edx,%1":"=g"(ax),"=g"(dx): :"eax","edx");
return (uint64_t(dx)<<32)+uint64_t(ax);
}
void f(std::vector<int> &v, int n){
for (int i = 0; i < n; i++) v.push_back(i);
for (int i = 0; i < n; i++) v.pop_back();
}
int main(int ac, char **ag){
int n = 1000;
if (ac > 1) n = atoi(ag[1]);
std::vector<int> v;
clock_t clk1 = clock();
uint64_t cpu1 = cputime();
f(v, n);
uint64_t cpu2 = cputime();
clock_t clk2 = clock();
std::cout << "cycle : " << cpu2 - cpu1 << std::endl;
std::cout << "clock : " << clk2 - clk1 << std::endl;
std::cout << "sec : " << (double)(clk2 - clk1)/CLOCKS_PER_SEC << std::endl;
}
ターミナルを起動し,
cd ~/mis2
g++-5 -O2 -o vector_speed vector_speed.cpp
を実行し,「コンパイル」する.「-O2」は最適化のオプションで,速度計測を目的とする場合は,こ
の程度の最適化レベルを用いる.コンパイルに成功したら,
./vector_speed 100000
を実行すると
cycle : 2296824
clock : 658
sec : 0.000658
のように,表示される.なお,プログラム中で,時間を計らなくても,
time ./vector_speed 100000
のようにしても,
real 0m0.011s
user 0m0.001s
sys 0m0.002s
のように表示されるが,計測の精度は落ちるし,プログラムの一部のみを計測することはできない.
プログラムの説明をする.
- atoi
「char *」型のCの文字列から,整数(int)に変換するC言語の関数.
- clock
OSの内部のclockの間隔(CLOCKS_PER_SEC, /usr/include/time.hに定義されている.MacOSのセンターに入っているバージョンでは1,000,000なので,1/1000000秒に1回増える)に基いたプロセス起動からの実行時間.OSによって計測の細かさが変わる.
- cputime()
アセンブリ言語命令 rdtsc(read time scamp counter) を用いて,CPU1サイクルにつき1カウントアップされるカウンタを読み出す.
自習問題
- 上のプログラムを自分のMacで実行してみて,fに与えるnの値をどう変化させるかによって,実行時間がどう変わるかを考えて見て下さい.
- 自分のMacで実行してみて,clockとcycleの関係から,CPUの速度が何GHzなのかを推計してみてください.
- vectorに変えて,list, dequeを使うプログラムに書き換えてみて,同様に実行時間を計測してみてください.