Rust 実行時間測定②

e-tipsmemo.hatenablog.com

このような記事を書いたが、time crateのリポジトリをよく見ると、

Notes
This library is no longer actively maintained, but bugfixes will be added (details).
In case you're looking for something a little fresher and more actively maintained have a look at the chrono crate.

とあった。
timeを計算するところでエラーがPCによっては出るようになってしまってメンテもされていないリポジトリなので使用を取りやめる。

なんとなく速くなっていることがわかりさえすればいいと思うので、'std::time'を使う。

Rust レイトレーシング ⑦床

http://e-tipsmemo.hatenablog.com/entry/2018/02/17/000000e-tipsmemo.hatenablog.com

複数の物体を表示できるようにする。

とりあえず複数の球体をvecに入れる。
shapelistにもHITトレイトを実装することで前と同じようにhitを呼ぶだけ。

t0 ~ closest間のものだけを当たった判定とするので、カメラに対し、一番近い物体のものが代表される。

床と球体を表示する。
床は半径の大きい球体で賄う。

じつは今まで画像を上下逆に描写していたらしいので最後にひっくり返すことにした。

実行結果。
f:id:katakanan:20180205003605p:plain:w300

本当は、

#[derive(Clone)]
pub struct ShapeList {
    pub v: Vec<Box<HIT + Send + Sync>>,
}

とできるのか?と思っていたがCloneがないとかなんとかで、thread間の共有ができるのかよくわからない。
意外とハマリポイントなのかもしれない。
球体だけならこのままの方法でゴールできる。
三角形などを表示したいときに困る。

Easy Origami (Dover Origami Papercraft)

Easy Origami (Dover Origami Papercraft)

Programming Rust: Fast, Safe Systems Development

Programming Rust: Fast, Safe Systems Development

MIPS 命令順序入れ替えない

前にこのような記事を書いたが、
e-tipsmemo.hatenablog.com

このままだとMIPSの遅延分岐やSW/LW関連の依存の解消のために勝手に命令が入れ替わってしまう。

解決法:
asmの先頭に.set noreorderをつける。

このプログラムを比較してみる。

add $1, $0, $10
add $2, $0, $11
L:addi $1, $1, 1
LW $3, 4($0)
nop
add $3, $1, $3
SW $3, 4($0)
bne $1, $2, L
nop
LW $4, 4($0)
nop
・・・

ない場合

ある場合

これは分岐する時点で普通のMIPSは分岐命令の次の命令をフェッチしてしまっているのでそこには
分岐(する|しない)にかかわらず、実行されるべき命令を置くように順番を変えてしまう。
[遅延分岐]

この場合、ストア命令は必ず実行され、分岐命令とは依存関係がないレジスタにアクセスしているのでストア命令で入れ替えられている。

コンピュータの構成と設計 第5版 上

コンピュータの構成と設計 第5版 上

コンピュータの構成と設計 第5版 下

コンピュータの構成と設計 第5版 下

Rust レイトレーシング ⑥ スーパーサンプリング


Rustでの演算子オーバーロードを行うために、構造体にAdd/Mul/Div Traitを実装する。

これを用いることで足し算、掛け算、割り算の演算子を使える。

スーパーサンプリングは光線の方向にランダムな要素を加えて、その方向から得られた色から平均をとることで物体のジャギを抑える事ができる。

rand::thread_rng().gen_range(a, b);

でa~bの乱数を得られる。 rand crateが必要なのでCargo.tomlに追加する。


ついでに実行時引数でスーパーサンプリングの回数を変更可能にした。

スーパーサンプリングを10回行った場合。
f:id:katakanan:20180202015103p:plain:w300

f:id:katakanan:20180202015220p:plain:w250f:id:katakanan:20180202015233p:plain:w250
左がスーパーサンプリングなし。
右がスーパーサンプリングあり。
なんとなくjpgっぽさが?ある

あと実行時間の比較。
f:id:katakanan:20180202015924p:plain
雑だがスレッド数8のときのほうが5倍ぐらい速い。


Programming Rust: Fast, Safe Systems Development

Programming Rust: Fast, Safe Systems Development

xgpiops.h No such flie or Directory

zyboでUSB3320のリセットがMIO46につながっているのは
Zybo Reference Manual [Reference.Digilentinc]
ここからわかる。
f:id:katakanan:20180205235840p:plain:w150
どうやらハードウェア類がLinux前にリセットされていなければならないのは組み込みあるあるなのかしらないが
以下のサイトによるとそうしなければならないようだ。
forum.digilentinc.com
しかし、肝心のコードを入れるとXIlinx SDKにxgpiops.hなんか無いと言われる。

結論。
bitstreamを作る前に、GPIO-MIOを使うように設定する。
f:id:katakanan:20180206000217p:plain

XSDKはVivadoから履かれたHDFをもとに、必要最低限なヘッダー類だけコピー・生成している。
結局「#include "xiicps.h"が無い」と同じことだった。

Zybo Zynq-7000 ARM/FPGA SoC Trainer Board

Zybo Zynq-7000 ARM/FPGA SoC Trainer Board

zybo自体は安い良いボードだと思うけど書籍はあまり充実していないなと思う。
というのも
情報はDigilentやネットで手に入ってしまう。
何よりもVivadoが頻繁に更新されてしまうので本に書かれる方法はすぐに古くなってしまうからであろうか。

Rust レイトレーシング ⑤ 法線

http://e-tipsmemo.hatenablog.com/entry/2018/02/05/000000e-tipsmemo.hatenablog.com
法線を用いて球に色を付ける。


交差した点の座標が必要。

あとは前回のものを微修正するだけでOK

法線を計算をしてHitRecordに詰める。


matchではSomeの中に引数のようなものを入れてそれを使用する。
法線は正規化されているので各要素は必ず1以下。そのまま色にして動作を確認する。

f:id:katakanan:20180201162901p:plain:w300
よさそう。


Programming Rust: Fast, Safe Systems Development

Programming Rust: Fast, Safe Systems Development

zybo ethernet Ubuntu 17 ipv4

0からzyboのLinux起動を試しており、イーサネットがつながらなかった。
e-tipsmemo.hatenablog.com
大体ここをベースに今回はUbuntu 17 (Artful)を利用する。

①デザイン

zyboのイーサネットピンをMIOから出す。MDIOを忘れないようにする。
f:id:katakanan:20180207210954p:plain
参考
f:id:katakanan:20180205235840p:plain:w200

②bitstreamをつくる。

省略

SDKを立ち上げてFSBLを作る。

省略

④Device treeをつくる。

ここが一番バージョンによって変わっているのか、ドライバが違うからだめなのかよくわからないが
とにかく、Digilentgithubにある書き方では動かなかった。(いままでは動いていた気がする)
動かなかった。。?書き方。
linux-Digilent-Dev/zynq-zybo.dts at master · Digilent/linux-Digilent-Dev · GitHub

ps7_ethernet_0: ps7-ethernet@e000b000 {
	#address-cells = <1>;
	#size-cells = <0>;
	clock-names = "ref_clk", "aper_clk";
	clocks = <&clkc 13>, <&clkc 30>;
	compatible = "xlnx,ps7-ethernet-1.00.a";
	interrupt-parent = <&ps7_scugic_0>;
	interrupts = <0 22 4>;
	phy-handle = <&phy0>;
	phy-mode = "rgmii-id";
	reg = <0xe000b000 0x1000>;
	xlnx,eth-mode = <0x1>;
	xlnx,has-mdio = <0x1>;
	xlnx,ptp-enet-clock = <108333336>;
	mdio {
		#address-cells = <1>;
		#size-cells = <0>;
		phy0: phy@1 {
			compatible = "realtek,RTL8211E";
			device_type = "ethernet-phy";
			reg = <1>;
		} ;
	} ;
} ;

これでも一応、eth0は出現するが

$ sudo ip link set eth0 up

でエラーが出る。

xemacps e000b000.ps7-ethernet: XEMACPS mii bus mii_probe fail.
xemacps e000b000.ps7-ethernet: eth0: no PHY found

device-tree-generatorを使ってみる。
xilinxの最新のdevice-tree-generatorを利用すると、全く違う構成になっている。

gem0: ethernet@e000b000 {
	compatible = "cdns,zynq-gem", "cdns,gem";
	reg = <0xe000b000 0x1000>;
	status = "disabled";
	interrupts = <0 22 4>;
	clocks = <&clkc 31>, <&clkc 31>, <&clkc 14>;
	clock-names = "pclk", "hclk", "tx_clk";
	#address-cells = <1>;
	#size-cells = <0>;
};

status="okay"に変更。
phy-modeを設定しているのは、pcw.dtsiにある。

&gem0 {
	phy-mode = "rgmii-id";
	status = "okay";
	xlnx,ptp-enet-clock = <0x6750918>;
};

ここはどうやらgem0本体と最終的に中身がマージされる。

あとはmdioの設定があるべきでそれは
system-top.dtsに置く?

mdio  {
	compatible= "cdns,macb-mdio";
	reg= <0xe000b000 0x1000>;
	clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>;
	clock-names = "pclk", "hclk", "tx_clk";
	#address-cells = <1>;
	#size-cells = <0>;
	eth_phy0:phy@1 {
		compatible = "realtek,RTL8211E";
		device_type = "ethernet-phy";
		reg = <0x1>;
	};
};

これを追加して(cpuなどと同じ階層)みたところ、なんかうまくいった。
compatibleの値はプローブされるときに必要になる気がしているが
それが違うということはなんかドライバが別なのだろうか・・?

bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk rootfstype=ext4 rootwait devtmpfs.mount=1";
も忘れないようにする。

Ubuntu ipv6の無効化

ここから先はUbuntuの設定

$ sudo ip link set eth0 up

をすると、NICが起きる(?)。
qiita.com
これをすれば無効にはなった。

ipv4 dhcp

なぜかipv4が降ってこなくて、ネットに繋がらなかった。
エトセ・ネットワーク・インターフェースはもういらないらしく、代わりにnetplanなるもので設定するらしい。
websiteforstudents.com

# This file describes the network interfaces available on your system
# For more information, see netplan(5).
network:
 version: 2
 renderer: networkd
 ethernets:
     eth0:
     dhcp4: yes

コマンドによって適用されるが、文法チェックを行ってくれるので安心。

sudo netplan apply

これでipv4が降ってきてpingが通った。
もしかしたら、
/etc/systemd/network/25-eth0.network

[Match]
Name=eth0

[Network]
DHCP=ipv4

が追加で必要かもしれない。