2015年6月22日月曜日

PAPIでのFLOPSの計算の方法

PAPI(Performance API)というものがあります。キャッシュヒット率、ミス率、FLOPS、命令の呼び出し回数などを計測できるAPIで、CPUの機能を使います。命令の呼び出し回数を計測できるので、今回は浮動小数点演算の呼び出し回数を計測してFLOPSを計測するのに使おうと思います

PAPIには高レベルAPIと低レベルAPIがあります。高レベルAPIにはまさにFLOPSを計算するためのPAPI_flops関数があります。これを計測したい処理の前後に挟むだけでFLOPSを取得できます。ただし、複数回計測する場合は値がリセットされないので入力時に-1を入れておく必要があります。

普段使う分には高レベルAPIを使えばいいですが高レベルAPIは並列化に対応していないのでopenmpなどで並列化したときは低レベルAPIを使う必要があります。低レベルAPIを使う場合は時間と実行命令数からFLOPSを計算する過程を自分で実装する必要があります。

参考

2015年6月21日日曜日

シュトラッセンのアルゴリズムの計算量

シュトラッセンのアルゴリズムという行列積を求めるアルゴリズムがあります。行列積を求めるときに部分行列の積を求めることによって演算回数が少なくて済みます。通常の行列積の演算は$O(n^3)$ですが、シュトラッセンのアルゴリズムを使うと$O(n^{\log_2 7})$で行えます。巷には日本語だとシュトラッセンのアルゴリズムの説明はちらほらありますが計算量について言及している説明はほとんどないのでしてみようと思います。

サイズNの正方行列の掛け算を考える。因みにシュトラッセンのアルゴリズムを使うときは正方行列でなかったら端に0だけの行or列を追加して無理やり正方行列にする必要がある。Nが2のべき乗でない場合は漸化式が途中で計算できなくなるので途中で諦めるか最初から諦める必要があると思う。以下Nは2のべき乗ということにする。サイズNの正方行列のシュトラッセンのアルゴリズムによる計算時間を$T(N)$と書く。シュトラッセンのアルゴリズムでは半分のサイズの行列積を7回求める。行列和の計算量は$O(N^2)$なので $$ T(N) = 7 T(N/2) + O(N^2) $$ となる。マスターの定理を使うと$O(N^{\log_2 7})$となる(らしい)。

マスターの定理はよくわからないのでマスターの定理を使わないで$T(N) = O(N^{\log_2 7})$を示す。 $$2^n := N$$ として $$U(n) := T(N)$$ と書くと $$U(n) = 7 U(n-1) + O(2^{2n})$$ となる。漸化式を解く感じで整理すると \begin{align*} &\frac{U(n)}{2^{2n}} + \frac{4}{3} c \leq \frac{7}{4} \left(\frac{U(n-1)}{2^{2n-2}} + \frac{4}{3}c\right)\\ &\leq \left(\frac{7}{4}\right) ^ n \left( U (0) + \frac{4}{3}c\right)\\ &\leq \left(\frac{7}{4}\right) ^ n c' (c'はなんかしらの定数) \end{align*} となるので $$ \frac{T(N)}{N^2} \leq c'\left(\frac{7}{4}\right) ^ {\log_2 N} $$ \begin{align*} T(N) &\leq c' N^2 \left(\frac{7}{4}\right) ^ {\log_2 N} \\ &= c'7 ^ {\log_2 N}\\ &= c'N ^ {\log_2 7} \end{align*} となり $$ T(N) = O(N^{\log_2 7}) $$ が示せた。

計算量解析をしてみたけれど数値計算的にはシュトラッセンのアルゴリズムはほとんど使われない。というのも

  • オーダは小さいけど定数が大きいから普通はシュトラッセンのアルゴリズムの方が時間がかかる
  • 疎行列だともっといい方法がある
  • 部分行列の計算のところでメモリを一杯食う
  • 足し引きを一杯行うから浮動小数点演算の誤差が一杯乗る
だからだそうだ。

参考

2015年5月14日木曜日

Evernoteとmarkdownで幸せになった話

最近 (と言っても結構前からほそぼそと使っていましたが) ノートや簡単なレポートやこのブログを書く環境にevernoteを組み込んでみたので書いてみる。

今までは主にmarkdownで書いてpandocをかましてlatex経由でpdf化していました。mediawikiを出力したかったりhtmlが欲しかったりslideにしたかったりということもありましたが、全部pandocで変換していました。pandocは素晴らしい。基本的に入力はemacsで行っています。この方法は特に悪くないんですが、しいて言うなら全部localのパソコンで完結しているので電車の中でスマホで内容を確認したり推敲したりということが出来ません。以前はDropboxを使っていましたが、容量がいっぱいになってしまって最近使ってませんでした。

そこでevernoteです!!evernoteはスマホとパソコンとの間での連携が非常に簡単です。というかスマホのクライアントが優秀です。スマホからテキストをいじる用途ではDropboxよりずっと使いやすいです。以前からevernoteは使っていましたが、evernoteはemacsで編集できません。 (余談ですが、以前はevernote-modeというものがあって割と便利でしたが今はもうAPIが変わったとかで動きません。)emacsで編集できないとなるとストレスが貯まります。このままでは死んでしまいます。

そこでgeeknoteというものがあります。geeknoteはevernoteをcliで操作できるすぐれものです。好きなエディタでevernoteを編集することができます。勿論editorにはemacsclientを登録します。そして、なんとgeeknoteではevernoteをmarkdownにして扱います。つまり、

スマホ -- evernoteアプリ --- evernote --- emacs --- markdown --- latex,html,...

という風にevernoteで何でも書けます。素晴らしいこれで何でもできますね。ちなみにこのブログを書く際にはgeeknote経由でmarkdownで出力したあとstackedit経由でBloggerに投稿しています。

2015年5月13日水曜日

FlycheckでVHDLのシンタックスチェック

FlycheckはEmacsでコードを書いている途中にリアルタイムでシンタックスチェックやコーディングスタイルのチェックを行ってくれる便利な拡張機能です。Flymakeと似ていますが、デフォルトで多くのシンタックスチェックが書かれています。僕は以前はFlymakeを使っていましたが、大体の言語でデフォルトの設定割とつかえるということと、自分でruleを書くのもFlymakeほどではないがそこまで難しくないのでFlycheckに乗り換えました。

僕は学科の課題などでVHDLを書くことがありますが、VHDLは比較的マイナーな言語だからか、無料でない処理系が多いからかFlycheckのルールがありませんでした。だから作りました。GHDLのシンタックスチェック機能を使いました。

最後のadd-hookのところでvhdl-modeでデフォルトでvhdl-ghdlのcheckerが使われるようになります。

2015年3月7日土曜日

Stumpwmを使おうと思ったけどやめた話

先日 http://sourceforge.jp/projects/tilingwm/wiki/FrontPage やらawesomeを使っている友人やらに感化されてタイル型ディスプレイマネージャーを使ってみようとおもった。その中でもStumpwmが(Emacsみたいに)拡張性が高そうで良さそうに感じたのでしばらく軽く使ってみた。そこで起こったいくつかの問題とか思ったことを書いてみる。

日本語入力がうまく行かない -> cjkみたいなimを使わないと生きていけない人の情報が少ない

ibus+mozcをここ何年か使っている。別にibusにこだわりがあるわけではないがとりあえずibusを使ってみようと思ったらどうにも入力ができていない。stumpwmについてはwikiとかに色々な情報があるにはあるが如何せんimを使う文化圏の人の情報が多くなくてibusとかについては調べてもだいぶ古い情報しか見つからなかった。やはり利用者がそれなりにいるor日本語ユーザの書いたドキュメントがある環境でないと辛いなと感じたときでした。(そういえば僕はこんな感じの理由で永らくVine Linuxを使ってましたね。今はArch Linuxを使っていますが。)

Commom Lisp環境についての知識がないとそんなに幸せになれない

僕はLisperではないです。Lisperではないですが、学科の課題でScheme処理系をSchemeで書いたりEmacs Lispの設定を書いたりするくらいにはLispは書けます。Common Lispも昔若干書いたことがあるので書けなくはないです。だからStumpwmを使おうかと思いました。しかしQuicklispとかasdfとかそういったCommon Lispを取り巻く周辺事情については全く知りません。Stumpwmにmoduleを追加したりしようと思ったらどうしてもその辺の知識が必要になるようです。Lisperになりたいなら勿論こういったことを勉強すればいいと思いますが、僕はLisperではなくて結局Unix文化圏の人でLispも書けなくはないくらいの人です。Window Managerを使うためにCommon Lispの世界に足を突っ込むのは割に合うのかと考えてしまった瞬間に僕は colon quitしてgnomeを開きました。gnomeはJavaScriptを知らなくても動きます。

つまり何を思ったか

僕はawkとかCとかbashとかが好きなUnix文化圏の人であってLisp文化圏の人ではない(と思っている)ので慣れない世界のものを中途半端に取り入れるのは辛いなあと。(そのくせEmacsは使ってるんだよなあ…)面白そうではあるのでしっかり時間が取れるときにちゃんと勉強したいなあと。

2015年2月20日金曜日

.emacs.dを書き直す会 第一弾

ここのところ.emacs.dの秘伝のタレ化が進んで非常に汚く、重くなってきたので.emacs.dを書き直した。第一弾として特定のモードに依らない設定を書いた。

package.el(melpa)

Emacs 24からデフォルトで入るようになったpackage管理。非常に便利なので引き続き使う。公式レポジトリだけだと足りないのでmelpaも追加する。marmaladeは以前は入れていたがひとまず入れないでみる。

(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
(package-initialize) 

init-loader

設定ファイルを分散して書けるようなもの。.emacs.d/inits以下に設定ファイルを書くと、辞書順に呼ばれる。

(require 'init-loader)
(init-loader-load)

twittering-mode

emacsからtweetするために必要。普段も使っていた。いつでも呟ける様にキーバインドを設定しておく。

(require 'twittering-mode)
(global-set-key "\C-xt" 'twittering-update-status-interactive)

appearance

特定のモードではなく背景色とかそういうもの。以前はXのクリップボードとemacsのコピーが同期されるようなものも書いていたが気がついたら勝手に同期されるようになっていた。背景色はthemeとかを使おうかと思ったが良さそうな色がなかったので”秘伝のタレ”を取り出した。

;;背景色の設定
( when window-system 
  (custom-set-faces
   '(default ((t
           (:background "#000040" :foreground "#e0e0e0")
           )))
   '(cursor ((((class color)
           (background dark))
          (:background "#00AA00"))
         (((class color)
           (background light))
          (:background "#999999"))
         (t ())
         ))))

;; フレーム透過設定
(add-to-list 'default-frame-alist '(alpha . (0.75 0.75)))
;; tool-barを消す
(tool-bar-mode 0)

;; C-h でbackspaceにする
(global-set-key "\C-h" 'delete-backward-char)

;; 括弧を強調表示
(show-paren-mode t)

helm

色々と便利な子。こいつがいないともうファイルも開けない。設定がよくわからなかったのでここも”秘伝のタレ”。

(when (require 'helm-config nil t)
  (helm-mode 1)

  (define-key global-map (kbd "M-x")     'helm-M-x)
  (define-key global-map (kbd "C-x C-f") 'helm-find-files)
  (define-key global-map (kbd "C-x C-r") 'helm-recentf)
  (define-key global-map (kbd "M-y")     'helm-show-kill-ring)
  (define-key global-map (kbd "C-c i")   'helm-imenu)
  (define-key global-map (kbd "C-x b")   'helm-buffers-list)

  (define-key helm-map (kbd "C-h") 'delete-backward-char)
  (define-key helm-find-files-map (kbd "C-h") 'delete-backward-char)
  (define-key helm-find-files-map (kbd "TAB") 'helm-execute-persistent-action)
  (define-key helm-find-files-map (kbd "C-z") 'helm-select-action)
  (define-key helm-read-file-map (kbd "TAB") 'helm-execute-persistent-action)

  ;; Disable helm in some functions
  (add-to-list 'helm-completing-read-handlers-alist '(find-alternate-file . nil))

  ;; Emulate `kill-line' in helm minibuffer
  (setq helm-delete-minibuffer-contents-from-point t)
  (defadvice helm-delete-minibuffer-contents (before helm-emulate-kill-line activate)
    "Emulate `kill-line' in helm minibuffer"
    (kill-new (buffer-substring (point) (field-end))))

  (defadvice helm-ff-kill-or-find-buffer-fname (around execute-only-if-exist activate)
    "Execute command only if CANDIDATE exists"
    (when (file-exists-p candidate)
      ad-do-it))

  (defadvice helm-ff-transform-fname-for-completion (around my-transform activate)
    "Transform the pattern to reflect my intention"
    (let* ((pattern (ad-get-arg 0))
           (input-pattern (file-name-nondirectory pattern))
           (dirname (file-name-directory pattern)))
      (setq input-pattern (replace-regexp-in-string "\\." "\\\\." input-pattern))
      (setq ad-return-value
            (concat dirname
                    (if (string-match "^\\^" input-pattern)
                        ;; '^' is a pattern for basename
                        ;; and not required because the directory name is prepended
                        (substring input-pattern 1)
                      (concat ".*" input-pattern)))))))

日本語入力

日本語入力は普段\C-\ではなく[変換/無変換]を使っているのでその辺の設定をまずする。(2015/02/25修正)Emacs 24.3以降でinactive-input-methodがobsoleteになったので修正した。

;; IMEの設定
(define-key global-map [zenkaku-hankaku] 'toggle-input-method)
;; 変換キーでIME ON
(define-key global-map [henkan]
  (lambda ()
    (interactive)
    (if current-input-method (deactivate-input-method))
    (toggle-input-method)))

;; 無変換キーでIME OFF
(define-key global-map [muhenkan]
  (lambda ()
    (interactive)
    (deactivate-input-method)))

次にmozcの設定。

;; mozc
(require 'mozc)
(setq default-input-method "japanese-mozc")

auto-complete

コードを書くときとかにいい感じで補完してくれる子。emacs lispを書くにもこれがないとつらい。Cとか特定の言語に依存する設定は後で。

(require 'auto-complete)
(require 'auto-complete-config)
(ac-config-default)

magit

emacsからgitを操作するもの。そう言えば結構前は標準で入るVCからgitを使っていたが、VCはgitに特化しておらず色々とやりたいことが出来なかったのでmagitにした。git rebase -iに当たるものをmagit-statusじゃない場所からやるとか使用頻度の少ないキーバインドは消した。

(require 'magit)
(global-set-key "\C-xgs" 'magit-status)
(global-set-key "\C-xgb" 'magit-branch-manager)

iedit

共通部分を全部まとめて編集するもの。変数名とかを変えるときに便利。”\C-;”と書きたいがそれだと動かないのでこんな感じで書いた。

;; iedit
(global-set-key [?\C-;] 'iedit-mode)

Written with StackEdit.

2015年1月1日木曜日

AwkLike classを作った

Google Apps Scriptでawkみたいな行志向でパターンマッチして動かしたくなったのでAwkLikeを作った。 こっから先は後日追記する。