Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vm benchmark tests #299

Merged
merged 52 commits into from
Dec 7, 2018
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
b0ec357
the initial bench version
mikevoronov Nov 22, 2018
9037b1a
add evd decomposition
mikevoronov Nov 23, 2018
d71ae44
update fibonacci
mikevoronov Nov 25, 2018
264c184
update recursive hash
mikevoronov Nov 26, 2018
75feb1b
introduce a new look of recursive hash test
mikevoronov Nov 26, 2018
17b3055
fibonacci and recursive hash final look
mikevoronov Nov 26, 2018
ff2ee07
some little improvements
mikevoronov Nov 27, 2018
e846aaa
introduce matrix tests
mikevoronov Nov 27, 2018
637cbc9
add eof
mikevoronov Nov 27, 2018
fc08f80
update factorization test
mikevoronov Nov 27, 2018
18711b2
update factorization test
mikevoronov Nov 27, 2018
4b188a2
rename bench_test to main because of wasmer doesn't support other fun…
mikevoronov Nov 27, 2018
9465e89
a little fix of cycle in recursive_hash test
mikevoronov Nov 27, 2018
08443b8
add some comments
mikevoronov Nov 27, 2018
e10c04c
add deflate test
mikevoronov Nov 27, 2018
617c98f
add bencher
mikevoronov Nov 29, 2018
96741c7
a little refactoring
mikevoronov Nov 29, 2018
9d11081
fix some minor bugs
mikevoronov Nov 29, 2018
a5424e2
change export functions scheme in tests
mikevoronov Nov 29, 2018
095411c
delete wagon runner
mikevoronov Nov 29, 2018
ee75d81
delete wagon runner
mikevoronov Nov 29, 2018
8982dd7
fix some bugs in vm launch
mikevoronov Nov 29, 2018
44d77bb
Merge branch 'vm_bench' of github.com:fluencelabs/fluence into vm_bench
mikevoronov Nov 29, 2018
4c69f1b
a little project rearrange
mikevoronov Nov 29, 2018
3c4a08a
move toone compression file for test with defalte and snappy compress…
mikevoronov Dec 3, 2018
e381ecf
introduce compression test final look
mikevoronov Dec 3, 2018
d891ab3
add comments and copyright headers
mikevoronov Dec 3, 2018
334cf76
update README.md
mikevoronov Dec 3, 2018
ab210ae
delete bencher and results
mikevoronov Dec 3, 2018
525103c
fix typos in readme
mikevoronov Dec 3, 2018
d891005
readme update
Dec 4, 2018
86229a4
readme update
Dec 4, 2018
6cf6e4f
change directories
mikevoronov Dec 4, 2018
673d6bb
udapte readme
mikevoronov Dec 4, 2018
49b8522
remove redundant readme from docs
mikevoronov Dec 4, 2018
29703ea
update readme
mikevoronov Dec 5, 2018
97958f6
remove redundant empty line
mikevoronov Dec 5, 2018
f5969ed
move README to tests directory
mikevoronov Dec 5, 2018
2a2ab03
fix author email and compression test name
mikevoronov Dec 5, 2018
3443eea
Merge branch 'master' into vm_bench_tests
mikevoronov Dec 6, 2018
d77202f
delete results from this pr
mikevoronov Dec 6, 2018
ac43815
Revert "delete results from this pr"
mikevoronov Dec 6, 2018
de78d03
changes authors in Cargo.toml
mikevoronov Dec 6, 2018
4867c9c
fix review comments
mikevoronov Dec 6, 2018
7f691ab
apply cargo fmt
mikevoronov Dec 6, 2018
0b1bd19
fix review suggestions
mikevoronov Dec 6, 2018
8b891b9
Merge branch 'master' into vm_bench_tests
mikevoronov Dec 6, 2018
49ffce3
fix bug with float type
mikevoronov Dec 7, 2018
5e9a5e1
add rust-toolchain file
mikevoronov Dec 7, 2018
e57bad4
add rust-toolchain to factorization_reikna
mikevoronov Dec 7, 2018
8bc7042
remove +nightly from README since rust-toolchain added
mikevoronov Dec 7, 2018
a763143
Merge branch 'master' into vm_bench_tests
mikevoronov Dec 7, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions bench/vm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
## VM benchmark tests

This microbenchmark consists of a few tests which can be used to measure performance of various WebAssembly virtual machines. It should be noted this benchmark is by definition is not comprehensive and might not reflect performance on real life workloads.

However, each test was crafted in a way that would prevent the virtual machine from optimizing them using the dead code elimination. Most tests also prevent intermediate results memoization (with `fibonacci_bigint` and `factorization_reikna` being exceptions) and allow to specify an RNG seed to obtain repeatable benchmark results.

Each test exports the `main` function which is called by the benchmark runner. There are also few compile-time parameters in each test that can be adjusted using the corresponding environment variables. The benchmark has been successfully tested on Mac and should run smoothly on Linux as well.

To run tests Rust Cargo package manager should be installed – the easiest way would be to follow these instructions:

```shell
# download and install rustup
curl -sSf https://static.rust-lang.org/rustup.sh | sh

# install the latest nightly toolchain
~/.cargo/bin/rustup toolchain install nightly

# make shure that Rust is up to date
rustup update

# install the Webassembly target for Rust
rustup target add wasm32-unknown-unknown --toolchain nightly
```
Below we also assume that Fluence GitHub repo has been already cloned and we are in the `vm_bench/tests` directory:

```shell
git clone --recursive https://github.com/fluencelabs/fluence
cd fluence/vm/vm_bench/tests
```

Random numbers in tests are generated with [IsaacRng](https://doc.rust-lang.org/1.0.0/rand/isaac/struct.IsaacRng.html). It should also be noted relative results of the QR and SVG decomposition tests can be somewhat different on different hardware because of the floating point non-determinism.

### Compression

This test compresses a sequence of `SEQUENCE_SIZE` bytes and has `ITERATIONS_COUNT` iterations of compressions. On each iteration a new sequence is generated by the seed that was computed based on the previous sequence. As the first seed the `SEED` parameter is used. Two compression algorithms ([deflate](https://docs.rs/deflate) and [snappy](https://docs.rs/snap)) are supported and can be chosen by specifying the `deflate_compression` flag.

To run:

```shell
cd recursive_hash
ITERATIONS_COUNT=1 SEED=1000000 SEQUENCE_SIZE=1024 cargo +nightly build --release --target wasm32-unknown-unknown [--feature "deflate_compression"]
```

### Factorization

This test factorizes provided `FACTORIZED_NUMBER` using [reikna](https://docs.rs/reikna/0.10.0/reikna/) library.

To run:

```shell
cd factorization_reikna
FACTORIZED_NUMBER=2147483647 cargo +nightly build --release --target wasm32-unknown-unknown
```

### Recursive fibonacci computing

This test recursively computes the Fibonacci number with the index `FIB_NUMBER`.

To run:

```shell
cd fibonacci_bigint
FIB_NUMBER=38 cargo +nightly build --release --target wasm32-unknown-unknown
```

### Matrix product

This test computes a product of random generated matrices of size `MATRIX_SIZE`. There are `ITERATIONS_COUNT` iterations; on each iteration new matrices are generated using the seed that was computed using the previous product result. As the first seed the `SEED` parameter is used.

To run:

```shell
cd matrix_product
ITERATIONS_COUNT=1000000 SEED=1 MATRIX_SIZE=10 cargo +nightly build --release --target wasm32-unknown-unknown
```

### Matrix QR decomposition

This test computes a QR decomposition of random generated matrices of size `MATRIX_SIZE`. There are `ITERATIONS_COUNT` iterations of decomposition; on each iteration a new matrix is generated using the seed that was computed using the previous decomposition result. As the first seed the `SEED` parameter is used.

To run:

```shell
cd matrix_qr_decomposition
ITERATIONS_COUNT=1000000 SEED=1 MATRIX_SIZE=10 cargo +nightly build --release --target wasm32-unknown-unknown
```

### Matrix SVD decomposition

This test computes an SVD decomposition of random generated matrices of size `MATRIX_SIZE`. There are `ITERATIONS_COUNT` iterations of decomposition; on each iteration a new matrix is generated using the seed that was computed using the previous decomposition result. As the first seed the `SEED` parameter is used.

To run:

```shell
cd matrix_svd_decomposition
ITERATIONS_COUNT=1000000 SEED=1 MATRIX_SIZE=10 cargo +nightly build --release --target wasm32-unknown-unknown
```

### Recursive hash computing

This test iteratively computes a hash chain `hash(hash( ... hash(x)))` of length `ITERATIONS_COUNT`, where `x` is the initial value specified by `INITIAL_VALUE`.

To run:

```shell
cd recursive_hash
ITERATIONS_COUNT=10000000 INITIAL_VALUE=0 cargo +nightly build --release --target wasm32-unknown-unknown
```
17 changes: 17 additions & 0 deletions bench/vm/tests/compression/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "snappy_compression"
version = "0.1.0"
authors = ["M. Voronov <[email protected]>"]

[lib]
crate-type = ["cdylib"]

[dependencies]
snap = "0.2"
deflate = "0.7.19"
rand = "0.6.1"
rand_isaac = "0.1.0"

[features]
default = []
deflate_compression = []
66 changes: 66 additions & 0 deletions bench/vm/tests/compression/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2018 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mod settings;

extern crate snap;
extern crate deflate;
extern crate rand;
extern crate rand_isaac;

use settings::{SEED, ITERATIONS_COUNT, SEQUENCE_SIZE};
use rand::{Rng, SeedableRng};
use rand_isaac::IsaacRng;
use deflate::deflate_bytes;

type Sequence = Vec<u8>;

/// generates pseudo-random byte sequence by given seed and given size
fn generate_sequence(seed : u64, size : u64) -> Sequence {
let mut rng: IsaacRng = SeedableRng::seed_from_u64(seed);
let mut result_sequence = Sequence::with_capacity(size as usize);

for _ in 0..size {
result_sequence.push(rng.gen::<u8>());
}
result_sequence
}

/// compresses provided sequence by deflate or snappy algorithm
fn compress_sequence(sequence: &Sequence) -> Sequence {
if cfg!(feature = "deflate_compression") {
return deflate_bytes(&sequence);
}

return snap::Encoder::new().compress_vec(&sequence).unwrap();
}

#[no_mangle]
pub extern "C" fn main() -> u64 {
let seed : u64 = SEED.parse::<u64>().unwrap();
let iterations_count : u64 = ITERATIONS_COUNT.parse::<u64>().unwrap();
let sequence_size : u64 = SEQUENCE_SIZE.parse::<u64>().unwrap();

let mut compressed_sequence = generate_sequence(seed, sequence_size);

for _ in 1..iterations_count {
let new_seed = compressed_sequence.len() +
compressed_sequence.iter().fold(0u8, |x1, x2| x1 ^ x2) as usize;
compressed_sequence = generate_sequence(new_seed as u64, sequence_size);
compressed_sequence = compress_sequence(&compressed_sequence);
}

compressed_sequence.iter().fold(0u8, |x1, x2| x1 ^ x2) as u64
}
mikevoronov marked this conversation as resolved.
Show resolved Hide resolved
23 changes: 23 additions & 0 deletions bench/vm/tests/compression/src/settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2018 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// this value is used as the first seed of pseudo-random generator for sequence generation
pub const SEED : &'static str = env!("SEED");
mikevoronov marked this conversation as resolved.
Show resolved Hide resolved

/// count of compression iterations
pub const ITERATIONS_COUNT: &'static str = env!("ITERATIONS_COUNT");

/// size of sequence that should be compressed on each iteration
pub const SEQUENCE_SIZE: &'static str = env!("SEQUENCE_SIZE");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think would be better to remove setting.rs file and define

mod setting {
...
}

inside lib.rs.
Now it looks redundant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AlI measurement results of these test are completely depend on parameters that defined in settings.rs file. So I think that it is better to have all adjusted parameters in separate file. Yes, there are two tests that have only one parameter but for foreign viewer it is more understandable what settings exactly have the current test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't more understandable when you have to see one 2 files instead of 1. And especially when one file has only a single line.
A 'setting' module as a separated module on the top of the file is good enough readable for a foreign viewer, I suggest.

10 changes: 10 additions & 0 deletions bench/vm/tests/factorization_reikna/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "factorization_reikna"
version = "0.1.0"
authors = ["M. Voronov <[email protected]>"]

[lib]
crate-type = ["cdylib"]

[dependencies]
reikna = "0.6.0"
29 changes: 29 additions & 0 deletions bench/vm/tests/factorization_reikna/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2018 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mod settings;
mikevoronov marked this conversation as resolved.
Show resolved Hide resolved
extern crate reikna;

use settings::FACTORIZED_NUMBER;
use reikna::prime;

#[no_mangle]
pub extern "C" fn main() -> u64 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extern "C" is not required and could be skipped.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not so easy question. Based on this article it can be said that [no_mangle] implies not only mangling absence but also participate in decision will this function be exported or not:

Ugh, linkage attributes are set on best effort basis. They can depend on 1) item being pub and being reachable from other crates 2) item being used in inline functions 3) #[no_mangle] 4) extern "ABI" 5) item being related to lang items 6) crate type - lib or exe. If the combination of all factors make an item likely to be used from the outside and linked to - let’s put an external linkage on it!

I think that this behavior is ugly but according to 4 part extern "C" increases the chance that this function will exported. So i suggest to leave it on all function that should be exported.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I investigated this question and that's what I dug:

  1. pub, extern and #[no_mangle] are required
  2. "C" is redundant

from here

Copy link
Member Author

@mikevoronov mikevoronov Dec 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it seems that cargo fmt adds "C". There is a separate option force_explicit_abi that by default is true in cargo fmt.

Also, from this link it isn't clear does ABI take part in decision of exporting function. I think that "C" may be useful later because of Rust is too young language and many things can differ in future.

let factorized_number : u64 = FACTORIZED_NUMBER.parse::<u64>().unwrap();
// reikna uses Atkin or Eratosthenes seive to factorize given number
let factors = prime::factorize(factorized_number);

factors[0]
}
17 changes: 17 additions & 0 deletions bench/vm/tests/factorization_reikna/src/settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2018 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// a number that should be factorized by this test
pub const FACTORIZED_NUMBER : &'static str = env!("FACTORIZED_NUMBER");
11 changes: 11 additions & 0 deletions bench/vm/tests/fibonacci_bigint/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "fibonacci_bigint"
version = "0.1.0"
authors = ["M. Voronov <[email protected]>"]

[lib]
crate-type = ["cdylib"]

[dependencies]
num-bigint = "0.2"
num-traits = "0.2"
40 changes: 40 additions & 0 deletions bench/vm/tests/fibonacci_bigint/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2018 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mod settings;
mikevoronov marked this conversation as resolved.
Show resolved Hide resolved
extern crate num_bigint;
extern crate num_traits;

use settings::FIB_NUMBER;
use num_bigint::BigUint;
use num_traits::One;
use std::ops::Sub;

/// recursively computes a fibonacci number F_num for the given num
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs require a first capital letter and dot at the end.

fn fib(num: &BigUint) -> BigUint {
if num.le(&BigUint::from(2u32)) {
return One::one();
}

fib(&num.sub(1u32)) + fib(&num.sub(2u32))
}

#[no_mangle]
pub extern "C" fn main() -> u8 {
let fib_number : BigUint = BigUint::from(FIB_NUMBER.parse::<u64>().unwrap());

fib(&fib_number).to_bytes_le().iter().fold(0u8, |x1, x2| x1 ^ x2)
mikevoronov marked this conversation as resolved.
Show resolved Hide resolved
}

17 changes: 17 additions & 0 deletions bench/vm/tests/fibonacci_bigint/src/settings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2018 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// a requested fibonacci number that would be computed
pub const FIB_NUMBER: &'static str = env!("FIB_NUMBER");
12 changes: 12 additions & 0 deletions bench/vm/tests/matrix_product/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "matrix_product"
version = "0.1.0"
authors = ["M. Voronov <[email protected]>"]

[lib]
crate-type = ["cdylib"]

[dependencies]
nalgebra = { version = "0.16", features = [ "alloc" ] }
rand = "0.6.1"
rand_isaac = "0.1.0"
Loading