Skip to content

Commit

Permalink
Make crate compile and pass tests on aarch64 platform
Browse files Browse the repository at this point in the history
**Description**
Use conditional compilation throughout the crate to make it compile and
run on aarch64 platform.

Mainly removed use of perfcnt crate and associated performance counters
on aarch64, revert to wall time for benchmark measurement.

One of the tagged pointer test started failing because u128 has a
different alignment on aarch64 versus x86. There is a rust-lang issue:
rust-lang/rust#54341

**Motivation**
This change is needed so I can develop this crate on an M1 mac.

**Testing Done**
 - `cargo test`
 - `cargo build --all-targets`
 - `cargo miri test`
  • Loading branch information
declanvk authored and Declan Kelly committed Nov 19, 2022
1 parent 543d273 commit f69e4f2
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ features = ["std", "rustc_1_57"]
[dev-dependencies]
argh = "0.1.7"
criterion = { version = "0.3.5", features = ["html_reports"] }
criterion-perf-events = "0.1.4"
perfcnt = "0.7.2"
dhat = "0.3.0"
rustc-hash = "1.1.0"

[target.'cfg(target_arch = "x86")'.dependencies]
criterion-perf-events = "0.1.4"
perfcnt = "0.7.2"

[[bench]]
name = "raw_apis"
harness = false
25 changes: 21 additions & 4 deletions benches/raw_apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,22 @@ use blart::{
},
LeafNode, NodePtr, OpaqueNodePtr,
};
#[cfg(not(target_arch = "x86"))]
use criterion::measurement::WallTime;
use criterion::{criterion_group, criterion_main, BenchmarkGroup, Criterion};
#[cfg(target_arch = "x86")]
use criterion_perf_events::Perf;
#[cfg(target_arch = "x86")]
use perfcnt::linux::{HardwareEventType, PerfCounterBuilderLinux};
use std::time::Duration;

#[cfg(target_arch = "x86")]
type Measurement = Perf;
#[cfg(not(target_arch = "x86"))]
type Measurement = WallTime;

fn run_benchmarks(
group: &mut BenchmarkGroup<Perf>,
group: &mut BenchmarkGroup<Measurement>,
key_vec: &[Box<[u8]>],
tree_root: OpaqueNodePtr<usize>,
) {
Expand Down Expand Up @@ -44,7 +53,7 @@ fn run_benchmarks(
}

fn setup_tree_run_benches_cleanup(
c: &mut Criterion<Perf>,
c: &mut Criterion<Measurement>,
keys: impl Iterator<Item = Box<[u8]>>,
group_name: &str,
) {
Expand All @@ -64,7 +73,7 @@ fn setup_tree_run_benches_cleanup(
unsafe { deallocate_tree(root) };
}

pub fn raw_api_benches(c: &mut Criterion<Perf>) {
pub fn raw_api_benches(c: &mut Criterion<Measurement>) {
// number of keys = 256
setup_tree_run_benches_cleanup(c, generate_keys_skewed(u8::MAX as usize), "skewed");
// number of keys = 256
Expand All @@ -89,7 +98,8 @@ pub fn raw_api_benches(c: &mut Criterion<Perf>) {
)
}

fn create_criterion_configuration() -> Criterion<Perf> {
#[cfg(target_arch = "x86")]
fn create_criterion_configuration() -> Criterion<Measurement> {
Criterion::default()
.with_measurement(Perf::new(PerfCounterBuilderLinux::from_hardware_event(
// I switched to using retired instruction counts because the variability of the wall
Expand All @@ -110,6 +120,13 @@ fn create_criterion_configuration() -> Criterion<Perf> {
.measurement_time(Duration::new(10, 0))
}

#[cfg(not(target_arch = "x86"))]
fn create_criterion_configuration() -> Criterion<Measurement> {
Criterion::default()
.sample_size(1000)
.measurement_time(Duration::new(10, 0))
}

criterion_group! {
name = benches;
config = create_criterion_configuration();
Expand Down
25 changes: 19 additions & 6 deletions src/tagged_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,12 +423,25 @@ mod tests {
0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111000usize
);

assert_eq!(TaggedPointer::<u128>::ALIGNMENT, 8);
assert_eq!(TaggedPointer::<u128>::NUM_BITS, 3);
assert_eq!(
TaggedPointer::<u128>::POINTER_MASK,
0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111000usize
);
// Something weird about the representation of u128 on x86 vs aarch64 platforms:
// https://github.com/rust-lang/rust/issues/54341
if cfg!(target_arch = "x86") {
assert_eq!(TaggedPointer::<u128>::ALIGNMENT, 8);
assert_eq!(TaggedPointer::<u128>::NUM_BITS, 3);

assert_eq!(
TaggedPointer::<u128>::POINTER_MASK,
0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111000usize
);
} else {
assert_eq!(TaggedPointer::<u128>::ALIGNMENT, 16);
assert_eq!(TaggedPointer::<u128>::NUM_BITS, 4);

assert_eq!(
TaggedPointer::<u128>::POINTER_MASK,
0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11110000usize
);
}
}

#[test]
Expand Down

0 comments on commit f69e4f2

Please sign in to comment.