何はともあれ画像を出力しないと何もできないので
image crateについて軽くメモ
左上が原点のようだ
このcargoとcrateの組み合わせで非常に簡単にライブラリの導入ができるのが頼もしい。
Ray Tracing in One Weekend (Ray Tracing Minibooks Book 1) (English Edition)
- 作者: Peter Shirley
- 発売日: 2016/01/26
- メディア: Kindle版
- この商品を含むブログを見る
何はともあれ画像を出力しないと何もできないので
image crateについて軽くメモ
左上が原点のようだ
このcargoとcrateの組み合わせで非常に簡単にライブラリの導入ができるのが頼もしい。
Ray Tracing in One Weekend (Ray Tracing Minibooks Book 1) (English Edition)
レイトレーシングを常々やってみようと思っていていた。
ちょうどよくRustという言語が波に乗り始めているらしいので
ついでにRustでレイトレーシングを書く
とは言っても0から何も見ずに書くのは学習も進まないので
Ray Tracing in One Weekend (Ray Tracing Minibooks Book 1) (English Edition)
本の方はステップアップ方式で書いてあるが完成形は既にアップロードされており
この本の筆者のgithubは以下である。
github.com
今回は準備編
$ cargo new rust_ray01 --bin $ cargo run Compiling rust_ray01 v0.1.0 () Finished dev [unoptimized + debuginfo] target(s) in 0.96 secs Running `target/debug/rust_ray01` Hello, world!
Cargo.tomlに以下を追記
[dependencies] image = "*" nalgebra = "*"
必要になったcrateは順次追加
ファイル分割を容易にするために、以下も追記
[lib] name = "renderer" path = "src/lib.rs"
./src/lib.rs
をmain.rsから見たrenderer crate
として使う?
core以下に色々と置く予定
main.rs
extern crate renderer; use renderer::*; fn main() { println!("Hello, world!"); println!("{}", hello()); }
lib.rs
extern crate image; extern crate nalgebra as ns; pub fn hello() -> String { "hello".to_string() }
$ cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.77 secs Running `target/debug/rust_ray01` Hello, world! hello
Ubuntu 17.04が出ました。
Ubuntu 17の名前はzesty
SDの第二パーティションをマウントして
ここと同じようにして
e-tipsmemo.hatenablog.com
$ sudo debootstrap --foreign --arch armhf zesty /mnt http://ports.ubuntu.com/ (略)
こっからもらってきて
github.com
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- xilinx_zynq_defconfig make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- UIMAGE_LOADADDR=0x8000 uImage
uImageができる。
ここからもらってきて
github.com
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- zynq_zybo_config make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
u-bootができる。
ここから
SDKを起動して
を作る
devicetreeは
github.com
を利用する。
e-tipsmemo.hatenablog.com
と同じだが、
devicetreeのbootargsに
console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=1
を指定する。
ZyboにSDを指して電源を入れる。
うまく行けばFSBLが起動してu-bootが起動してKernelに制御が移って、
第二パーティションのUbuntuのルートファイルシステムを展開してくれる。
zybo@ubuntu:~$ cat /etc/os-release NAME="Ubuntu" VERSION="17.04 (Zesty Zapus)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 17.04" VERSION_ID="17.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=zesty UBUNTU_CODENAME=zesty zybo@ubuntu:~$ zybo@ubuntu:~$ cat /proc/cpuinfo processor : 0 model name : ARMv7 Processor rev 0 (v7l) BogoMIPS : 650.00 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x3 CPU part : 0xc09 CPU revision : 0 processor : 1 model name : ARMv7 Processor rev 0 (v7l) BogoMIPS : 650.00 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32 CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x3 CPU part : 0xc09 CPU revision : 0 Hardware : Xilinx Zynq Platform Revision : 0003 Serial : 0000000000000000 zybo@ubuntu:~$
よさそう
Zybo Zynq-7000 ARM/FPGA SoC Trainer Board
ARM Cortex-A9×2! ZynqでワンチップLinux on FPGA (*ボードは付属していません) (Design Wave)
e-tipsmemo.hatenablog.com
このような記事を書いたが、そもそもthreadをたくさんjoinした後に、
その後の処理はそれらスレッドの終了を待っているのだろうか。と思ったので確認してみた。
#[cfg(test)] mod tests { use super::*; fn hoge(thread: u32, num: u32) -> u32 { for x in 0..num { println!("th:{}, count:{}", thread, x); thread::sleep(std::time::Duration::from_millis(1000)); } thread } #[test] fn thread_barrer() { let v = vec![20, 30, 10, 15, 17]; let mut children = vec![]; for t in 0..v.len() { let num = v[t as usize]; children.push(thread::spawn(move || hoge(t as u32, num))); } let mut ret = vec![]; for child in children { ret.push(child.join().unwrap()); } println!("{:?}", ret.iter().fold(0, |s, &t| s + t)); } }
結果としてこのプログラムは全てのchild threadがおわってから次の処理を行うという意図したものになってた。
$ cargo test Compiling multi v0.1.0 (*** ) Finished dev [unoptimized + debuginfo] target(s) in 1.3 secs Running target/debug/deps/multi-1bf733f9a047a566 running 1 test th:2, count:0 (略) th:2, count:3 th:1, count:3 th:3, count:3 th:0, count:3 th:4, count:3 th:1, count:4 th:4, count:4 th:2, count:4 th:3, count:4 th:0, count:4 th:0, count:5 th:3, count:5 th:4, count:5 th:2, count:5 th:1, count:5 (略) th:0, count:12 th:1, count:12 th:3, count:12 th:4, count:12 th:0, count:13 th:4, count:13 th:3, count:13 th:1, count:13 th:0, count:14 (略) th:1, count:20 th:1, count:21 th:1, count:22 th:1, count:23 th:1, count:24 th:1, count:25 th:1, count:26 th:1, count:27 th:1, count:28 th:1, count:29 10 . test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured
Correct way to wait until all threads are finished
結論:勝手に待ってくれている。
並行コンピューティング技法 ―実践マルチコア/マルチスレッドプログラミング
Mastering Rust: Advanced concurrency, macros, and safe database
CypreeのEZ-USB FX2を開発するために必要なものをメモする
まずは登録しないといけないのが不便
あとサイプレスのサイトがとても重い。
Windows10のためのドライバ
http://japan.cypress.com/knowledge-base-article/drivers-ez-usb-fx1-fx2lp-and-fx3-kba94413
開発ソフトウェアはFX2LP用のSDKがあるがKeilコンパイラを使用してIDEも使いにくい
http://japan.cypress.com/documentation/development-kitsboards/cy3684-ez-usb-fx2lp-development-kit
EZ-USB FX2には8051
という8bit CPUが載っており
Cypress付属のコンパイラ のKail Compilerでは4KBまでのプログラムしかコンパイルすることができない。
EclipseでFX3のSDKを入れる。これには同時にFX2LPの開発もできるようになっている。
www.cypress.com
この中には
Cypress Console
http://japan.cypress.com/documentation/software-and-drivers/suiteusb-34-usb-development-tools-visual-studio
も既に入っている。
コンパイラは付属していなので
Keilコンパイラの代わりにSDCCコンパイラを入れる。
SDCC - Small Device C Compiler
SDCCをProgram Files以下にインストールするとEclipseがProgramをコマンドだと思うようになるのでC:\SDCCにインストールした。
すべてをインストールする。
すべてのプログラムのCypressの中に
Cypress EZ USB SuiteというEclipseベースのIDEがある。
File->Project でCypessを展開すると、FX2LP Projectがある
Bulkloopをテンプレートにプリジェクトを作成できる。
デバイスマネージャーにCypress FX2LP No EEPROM Device
と出ればOK
Cypress Control Centerを起動して、Cypress No Flash を選択する。
ツールバーのProgram FX2からRAMに
ビルドしたサンプルプログラムのディレクトリ内にあるbulklo]op.hexを選択し、書き込む。
左下のProgramm....が Successに変われば書き込み完了である。
プログラムを書き込んで数十秒立つと、Cypress Control Center上でのFX2 の表示が
Cypress FX2LP Sample Deviceに代わっている。
要素を展開して、Endpointを指定し、転送を開始すると0を
Byte to transferのサイズだけ送信するテストが動く。
Text to send にテキストを入力するとそのバイトサイズだけ転送される。
次からは以下の書籍を参考にしていこうと思う。(しかし絶版らしい)
Myoffice 開発ボードUSB2.0 EZ-USB FX2LP 13A USB2.0 開発基板
multithreadが本当に効いているのかを確かめたいので
シングルスレッドとマルチスレッドで実行時間を測定したかった。
しかし、
ここのような
e-tipsmemo.hatenablog.com
cargo banchによる測定方法ではなんだかうまくいかなかったので
シンプルに実行前後の時間の差分をとる補法で比較した。
time crateを使うのでCargo.tomlに追記する。
[dependencies] time = "*"
main.rs
extern crate time; use std::u32; use std::thread; use std::sync::{Arc, Mutex}; use test::test::Bencher; use time::precise_time_ns; #[derive(Debug, Copy, Clone)] struct Fx { a: f64, b: f64, step: u64, f: fn(f64) -> f64, } impl Fx { fn new(a: f64, b: f64, step: u64, f: fn(f64) -> f64) -> Fx { Fx { a: a, b: b, step: step, f: f, } } } fn integral(p: &Fx) -> f64 { let dx = (p.b - p.a) / (p.step as f64); let mut sum = 0.0; for n in 0..p.step { let x = p.a + dx * (n as f64); let bar = ((p.f)(x) + (p.f)(x + dx)) * dx / 2.0; sum = sum + bar; } sum } #[cfg(test)] mod tests { use super::*; const a: f64 = 0.0; const b: f64 = 1.0; const thread: u64 = 4; const onestep: u64 = 100000000; fn f(x: f64) -> f64 { x * x + 1.0 } #[test] fn int_test() { let prim = Fx::new(a, b, thread * onestep, f); let t0 = precise_time_ns(); let ret = integral(&prim); let t1 = precise_time_ns(); println!("single:{:?}", ret); println!("exec time:{}", t1 - t0); } #[test] fn int_thread_test() { let mut pvec = vec![]; let x = (b - a) / (thread as f64); let ti = thread as usize; for t in 0..thread { let at = a + x * (t as f64); let bt = a + x * (t as f64) + x; let prim = Fx::new(at, bt, onestep, f); pvec.push(prim); } let mut children = vec![]; let mut data = vec![]; for i in 0..ti { let p = pvec[i]; children.push(thread::spawn(move || integral(&p))); } let t0 = precise_time_ns(); for child in children { data.push(child.join().unwrap()); } let res = data.iter().fold(0.0, |s, &t| s + t); let t1 = precise_time_ns(); println!("{:?}", data); println!("multi:{:?}", res); println!("exec time:{}", t1 - t0); } } fn main() { let handle = thread::spawn(|| { println!("Hello, thread World!"); }); let _ = handle.join(); }
実行結果
$ cargo test running 2 tests [0.255208333333325, 0.2864583333333229, 0.3489583333333, 0.44270833333330617] multi:1.333333333333254 exec time:12128613000 .single:1.3333333333333182 exec time:30163525000 . test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured
速く。。なっている?気がする。
これは実行部分の時間しか測定しておらず、
ThreadHandleを取得するところも含めるとマルチスレッドを使用したほうが時間がかかることになる。
なのでトータルでの実行時間を速くするためにはThreadHandleを取得する時間が支配的にならないようなアプリで使ワなければ意味がない。
Programming Rust: Fast, Safe Systems Development
並行コンピューティング技法 ―実践マルチコア/マルチスレッドプログラミング
組み込みLinuxの勉強として
あるARMデバイスのためにSDカードのパーティションにUbuntuのRoot File Systemを展開しておきたい。
タイトルはBuild
とあるがビルドするほどのものでもないかもしれない。
実行環境はVMplayer上のUbuntu16.04 LTS
$ sudo apt-get install qemu-user-static
今回はSDカードの第二パーティションにRoot File Systemを展開したいので事前にそうしておく。
$ sudo gparted /dev/sdb
などで
とする
$ sudo mount -o loop /dev/sdX2 /mnt
ここを見て
Index of /dists
自分の欲しいUbuntuのバージョンの名前?をコマンドの適切な位置に入れる。
例えば
16.04 LTSならxenial
14.04 LTSならtrusty
sudo debootstrap --foreign --arch armhf [Ubuntuのバージョン] /mnt http://ports.ubuntu.com/ sudo cp /usr/bin/qemu-arm-static /mnt/usr/bin/ sudo chroot /mnt /usr/bin/groups: cannot find name for group ID 0 I have no name!@ubuntu:/#
これでchrootした
ここからは、chroot以下での作業
I have no name!@ubuntu:/# ./debootstrap/debootstrap --second-stage I have no name!@ubuntu:/# passwd (略) I have no name!@ubuntu:/# su root@ubuntu:/# passwd (念のため) (略) root@ubuntu:/# apt-get update (略) root@ubuntu:/# adduesr hoge (略:パスワードは設定する)
/home以下にhogeのフォルダができている。
または
root@ubuntu:/# cat /etc/passwd
でhogeユーザーがいることを確かめて終了
これで一応Root File System の展開は終了。
・・続く