# HG changeset patch # User ellis # Date 1699242406 18000 # Node ID 0c8a74e62d77b1393863c4bd6e979b9d6765741d # Parent e19807ed02aac209fa82ee82b7587ee1487bf6be nas-t migrate diff -r e19807ed02aa -r 0c8a74e62d77 .hgsubstate --- a/.hgsubstate Sun Nov 05 21:55:26 2023 -0500 +++ b/.hgsubstate Sun Nov 05 22:46:46 2023 -0500 @@ -1,2 +1,2 @@ 9dd35bc56a8153d97d2a1d2556affca62558d656 blog -087da4ed0df6882a7f0c7acfb9f990b9c329e4f7 docs +bd85a72319d85b4cc4d96df2459a6c500ec26271 docs diff -r e19807ed02aa -r 0c8a74e62d77 scratch/20231105.org --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scratch/20231105.org Sun Nov 05 22:46:46 2023 -0500 @@ -0,0 +1,136 @@ +* DRAFT dylib-skel-1 +- State "DRAFT" from [2023-11-05 Sun 22:23] +** Overview +Our core languages are [[https://www.rust-lang.org/][Rust]] and [[https://lisp-lang.org/][Lisp]] - this is the killer combo which will allow NAS-T +to rapidly develop high-quality software. As such, it's crucial that these two very +different languages (i.e. compilers) are able to interoperate seamlessly. + +Some interop methods are easy to accomodate via the OS - such as IPC or data sharing, +but others are a bit more difficult. + +In this 2-part series we'll build a FFI bridge between Rust and Lisp, which is something +that /can/ be difficult, due to some complications with Rust and because this is not the +most popular software stack (yet ;). This is an experiment and may not make it to our +code-base, but it's definitely something worth adding to the toolbox in case we need it. + +** FFI +The level of interop we're after in this case is [[https://en.wikipedia.org/wiki/Foreign_function_interface][FFI]]. + +Basically, calling Rust code from Lisp and vice-versa. There's an article about calling +Rust from Common Lisp [[https://dev.to/veer66/calling-rust-from-common-lisp-45c5][here]] which shows the basics and serves as a great starting point +for those interested. +*** Rust != C +The complication(s) with Rust I mentioned early is really just that /it is not C/. =C= +is old, i.e. well-supported with a stable ABI, making the process of creating bindings +for a C library a breeze in many languages. + +For a Rust library we need to first appease the compiler, as explained in [[https://doc.rust-lang.org/nomicon/ffi.html#calling-rust-code-from-c][this section]] +of the Rustonomicon. Among other things it involves changing the calling-convention of +functions with a type signature and editing the Cargo.toml file to produce a +C-compatible ABI binary. The Rust default ABI is unstable and can't reliably be used +like the C ABI can. + +*** Overhead +Using FFI involves some overhead. Check [[https://github.com/dyu/ffi-overhead][here]] for an example benchmark across a few +languages. While building the NAS-T core, I'm very much aware of this, and will need a +few sanity benchmarks to make sure the cost doesn't outweigh the benefit. In particular, +I'm concerned about crossing multiple language barriers (Rust<->C<->Lisp). + +** Rust -> C -> Lisp +*** Setup +For starters, I'm going to assume we all have Rust (via =rustup=) and Lisp (=sbcl= only) +installed on our GNU/Linux system (some tweaks needed for Darwin/Windows, not covered in +this post). +**** Cargo +Create a new library crate. For this example we're focusing on a 'skeleton' for +/dynamic/ libraries only, so our experiment will be called =dylib-skel= or *dysk* for +short. +src_sh[:exports code]{cargo init dysk --lib && cd dysk} + +A =src/lib.rs= will be generated for you. Go ahead and delete that. We're going to be +making our own =lib.rs= file directly in the root directory (just to be cool). + +The next step is to edit your =Cargo.toml= file. Add these lines after the =[package]= +section and before =[dependencies]=: +#+begin_src conf-toml +[lib] +crate-type = ["cdylib","rlib"] +path = "lib.rs" +[[bin]] +name="dysk-test" +path="test.rs" +#+end_src + +This tells Rust to generate a shared C-compatible object with a =.so= extension which we +can open using [[https://man.archlinux.org/man/dlopen.3.en][dlopen]]. +**** cbindgen +***** install +Next, we want the =cbindgen= program which we'll use to generate header files for +C/C++. This step isn't necessary at all, we just want it for further experimentation. + +src_sh[:exports code]{cargo install --force cbindgen} + +We append the =cbindgen= crate as a /build dependency/ to our =Cargo.toml= like so: +#+begin_src conf-toml +[build-dependencies] +cbindgen = "0.24" +#+end_src +***** cbindgen.toml +#+begin_src conf-toml :tangle cbindgen.toml +language = "C" +autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */" +include_version = true +namespace = "dysk" +cpp_compat = true +after_includes = "#define DYSK_VERSION \"0.1.0\"" +line_length = 88 +tab_width = 2 +documentation = true +documentation_style = "c99" +usize_is_size_t = true +[cython] +header = '"dysk.h"' +#+end_src +***** build.rs +#+begin_src rust :tangle build.rs +fn main() -> Result<(), cbindgen::Error> { + if let Ok(b) = cbindgen::generate(std::env::var("CARGO_MANIFEST_DIR").unwrap()) { + b.write_to_file("dysk.h"); Ok(())} + else { panic!("failed to generate dysk.h from cbindgen.toml") } } +#+end_src +*** lib.rs +#+begin_src rust :tangle lib.rs +//! lib.rs --- dysk library +use std::ffi::{c_char, c_int, CString}; +#[no_mangle] +pub extern "C" fn dysk_hello() -> *const c_char { + CString::new("hello from rust").unwrap().into_raw()} +#[no_mangle] +pub extern "C" fn dysk_plus(a:c_int,b:c_int) -> c_int {a+b} +#[no_mangle] +pub extern "C" fn dysk_plus1(n:c_int) -> c_int {n+1} +#+end_src +*** test.rs +#+begin_src rust :tangle test.rs +//! test.rs --- dysk test +fn main() { let mut i = 0u32; while i < 500000000 {i+=1; dysk::dysk_plus1(2 as core::ffi::c_int);}} +#+end_src +*** compile +#+begin_src sh +cargo build --release +#+end_src +*** load from SBCL +#+begin_src lisp :tangle dysk.lisp +(load-shared-object #P"target/release/libdysk.so") +(define-alien-routine dysk-hello c-string) +(define-alien-routine dysk-plus int (a int) (b int)) +(define-alien-routine dysk-plus1 int (n int)) +(dysk-hello) ;; => "hello from rust" +#+end_src +*** benchmark +#+begin_src shell +time target/release/dysk-test +#+end_src +#+begin_src lisp :tangle test.lisp +(time (dotimes (_ 500000000) (dysk-plus1 2))) +#+end_src diff -r e19807ed02aa -r 0c8a74e62d77 scratch/refs.bib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scratch/refs.bib Sun Nov 05 22:46:46 2023 -0500 @@ -0,0 +1,169 @@ +@article{btrfs, +author = {Rodeh, Ohad and Bacik, Josef and Mason, Chris}, +year = {2013}, +month = {08}, +pages = {}, +title = {BTRFS: The linux B-tree filesystem}, +volume = {9}, +journal = {ACM Transactions on Storage (TOS)}, +doi = {10.1145/2501620.2501623} +} +@INPROCEEDINGS{zfs, + author={Rodeh, O. and Teperman, A.}, + booktitle={20th IEEE/11th NASA Goddard Conference on Mass Storage Systems and Technologies, 2003. (MSST 2003). Proceedings.}, + title={zFS - a scalable distributed file system using object disks}, + year={2003}, + volume={}, + number={}, + pages={207-218}, + doi={10.1109/MASS.2003.1194858}} + +@inproceedings{tmpfs, + title={tmpfs: A Virtual Memory File System}, + author={Peter Snyder}, + year={1990}, + url={https://api.semanticscholar.org/CorpusID:54156693} +} + +@Article{nvme-ssd-ux, +AUTHOR = {Kim, Seongmin and Kim, Kyusik and Shin, Heeyoung and Kim, Taeseok}, +TITLE = {Practical Enhancement of User Experience in NVMe SSDs}, +JOURNAL = {Applied Sciences}, +VOLUME = {10}, +YEAR = {2020}, +NUMBER = {14}, +ARTICLE-NUMBER = {4765}, +URL = {https://www.mdpi.com/2076-3417/10/14/4765}, +ISSN = {2076-3417}, +DOI = {10.3390/app10144765} +} + +@inproceedings{ext4, +author = {Djordjevic, Borislav and Timcenko, Valentina}, +title = {Ext4 File System Performance Analysis in Linux Environment}, +year = {2011}, +isbn = {9781618040282}, +publisher = {World Scientific and Engineering Academy and Society (WSEAS)}, +address = {Stevens Point, Wisconsin, USA}, +booktitle = {Proceedings of the 11th WSEAS International Conference on Applied Informatics and Communications, and Proceedings of the 4th WSEAS International Conference on Biomedical Electronics and Biomedical Informatics, and Proceedings of the International Conference on Computational Engineering in Systems Applications}, +pages = {288–293}, +numpages = {6}, +keywords = {Linux, journaling, ext4/ext3/ext2, filesystems, inodes, disk performances, file block allocation}, +location = {Florence, Italy}, +series = {AIASABEBI'11} +} + +@Article{hd-failure-ml, +AUTHOR = {Zhang, Mingyu and Ge, Wenqiang and Tang, Ruichun and Liu, Peishun}, +TITLE = {Hard Disk Failure Prediction Based on Blending Ensemble Learning}, +JOURNAL = {Applied Sciences}, +VOLUME = {13}, +YEAR = {2023}, +NUMBER = {5}, +ARTICLE-NUMBER = {3288}, +URL = {https://www.mdpi.com/2076-3417/13/5/3288}, +ISSN = {2076-3417}, +DOI = {10.3390/app13053288} +} + +@inproceedings{smart-ssd-qp, +author = {Do, Jaeyoung and Kee, Yang-Suk and Patel, Jignesh M. and Park, Chanik and Park, Kwanghyun and DeWitt, David J.}, +title = {Query Processing on Smart SSDs: Opportunities and Challenges}, +year = {2013}, +isbn = {9781450320375}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +url = {https://doi.org/10.1145/2463676.2465295}, +doi = {10.1145/2463676.2465295}, +booktitle = {Proceedings of the 2013 ACM SIGMOD International Conference on Management of Data}, +pages = {1221–1230}, +numpages = {10}, +keywords = {smart ssd}, +location = {New York, New York, USA}, +series = {SIGMOD '13} +} + +@inproceedings{ssd-perf-opt, +author = {Zuck, Aviad and G\"{u}hring, Philipp and Zhang, Tao and Porter, Donald E. and Tsafrir, Dan}, +title = {Why and How to Increase SSD Performance Transparency}, +year = {2019}, +isbn = {9781450367271}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +url = {https://doi.org/10.1145/3317550.3321430}, +doi = {10.1145/3317550.3321430}, +booktitle = {Proceedings of the Workshop on Hot Topics in Operating Systems}, +pages = {192–200}, +numpages = {9}, +location = {Bertinoro, Italy}, +series = {HotOS '19} +} + +@article{flash-openssd-systems, +author = {Kwak, Jaewook and Lee, Sangjin and Park, Kibin and Jeong, Jinwoo and Song, Yong Ho}, +title = {Cosmos+ OpenSSD: Rapid Prototype for Flash Storage Systems}, +year = {2020}, +issue_date = {August 2020}, +publisher = {Association for Computing Machinery}, +address = {New York, NY, USA}, +volume = {16}, +number = {3}, +issn = {1553-3077}, +url = {https://doi.org/10.1145/3385073}, +doi = {10.1145/3385073}, +journal = {ACM Trans. Storage}, +month = {jul}, +articleno = {15}, +numpages = {35}, +keywords = {storage system, solid state drive (SSD), flash translation layer (FTL), Flash memory} +} + +@INPROCEEDINGS{emmc-mobile-io, + author={Zhou, Deng and Pan, Wen and Wang, Wei and Xie, Tao}, + booktitle={2015 IEEE International Symposium on Workload Characterization}, + title={I/O Characteristics of Smartphone Applications and Their Implications for eMMC Design}, + year={2015}, + volume={}, + number={}, + pages={12-21}, + doi={10.1109/IISWC.2015.8}} + +@inproceedings{xfs-scalability, + author = {Adam Sweeney and + Doug Doucette and + Wei Hu and + Curtis Anderson and + Mike Nishimoto and + Geoff Peck}, + title = {Scalability in the {XFS} File System}, + booktitle = {Proceedings of the {USENIX} Annual Technical Conference, San Diego, + California, USA, January 22-26, 1996}, + pages = {1--14}, + publisher = {{USENIX} Association}, + year = {1996}, + url = {http://www.usenix.org/publications/library/proceedings/sd96/sweeney.html}, + timestamp = {Wed, 04 Jul 2018 13:06:34 +0200}, + biburl = {https://dblp.org/rec/conf/usenix/Sweeney96.bib}, + bibsource = {dblp computer science bibliography, https://dblp.org} +} + +@inproceedings{xfs, + title={xFS: A wide area mass storage file system}, + author={Wang, Randolph Y and Anderson, Thomas E}, + booktitle={Proceedings of IEEE 4th Workshop on Workstation Operating Systems. WWOS-III}, + pages={71--78}, + year={1993}, + organization={IEEE} +} + +@inproceedings {zns-usenix, +author = {Matias Bj{\o}rling and Abutalib Aghayev and Hans Holmberg and Aravind Ramesh and Damien Le Moal and Gregory R. Ganger and George Amvrosiadis}, +title = {{ZNS}: Avoiding the Block Interface Tax for Flash-based {SSDs}}, +booktitle = {2021 USENIX Annual Technical Conference (USENIX ATC 21)}, +year = {2021}, +isbn = {978-1-939133-23-6}, +pages = {689--703}, +url = {https://www.usenix.org/conference/atc21/presentation/bjorling}, +publisher = {USENIX Association}, +month = jul, +} \ No newline at end of file