From 3250e655007a2140898d46c04df0f48c2f149dd2 Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 2 Jan 2014 19:48:30 +0100 Subject: [PATCH 1/3] libextra: Add benchmarks for ebml::reader::vuint_at() --- src/libextra/ebml.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs index b63f7e495b90..4a47af46afe0 100644 --- a/src/libextra/ebml.rs +++ b/src/libextra/ebml.rs @@ -960,3 +960,87 @@ mod tests { test_v(Some(3)); } } + +#[cfg(test)] +mod bench { + use ebml::reader; + use test::BenchHarness; + + #[bench] + pub fn vuint_at_A_aligned(bh: &mut BenchHarness) { + use std::vec; + let data = vec::from_fn(4*100, |i| { + match (i % 2) { + 0 => 0x80u8, + _ => i as u8, + } + }); + let mut sum = 0u; + bh.iter(|| { + let mut i = 0; + while (i < data.len()) { + sum += reader::vuint_at(data, i).val; + i += 4; + } + }); + } + + #[bench] + pub fn vuint_at_A_unaligned(bh: &mut BenchHarness) { + use std::vec; + let data = vec::from_fn(4*100+1, |i| { + match (i % 2) { + 1 => 0x80u8, + _ => i as u8 + } + }); + let mut sum = 0u; + bh.iter(|| { + let mut i = 1; + while (i < data.len()) { + sum += reader::vuint_at(data, i).val; + i += 4; + } + }); + } + + #[bench] + pub fn vuint_at_D_aligned(bh: &mut BenchHarness) { + use std::vec; + let data = vec::from_fn(4*100, |i| { + match (i % 4) { + 0 => 0x10u8, + 3 => i as u8, + _ => 0u8 + } + }); + let mut sum = 0u; + bh.iter(|| { + let mut i = 0; + while (i < data.len()) { + sum += reader::vuint_at(data, i).val; + i += 4; + } + }); + } + + #[bench] + pub fn vuint_at_D_unaligned(bh: &mut BenchHarness) { + use std::vec; + let data = vec::from_fn(4*100+1, |i| { + match (i % 4) { + 1 => 0x10u8, + 0 => i as u8, + _ => 0u8 + } + }); + let mut sum = 0u; + bh.iter(|| { + let mut i = 1; + while (i < data.len()) { + sum += reader::vuint_at(data, i).val; + i += 4; + } + }); + } +} From 1749d611254a4ae8992daa591fc5e60e652028fa Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Thu, 2 Jan 2014 23:22:07 +0100 Subject: [PATCH 2/3] libstd: Always inline all byteswap functions --- src/libstd/unstable/intrinsics.rs | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index e0089b599c5b..bc88abaae973 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -486,33 +486,33 @@ extern "rust-intrinsic" { pub fn u64_mul_with_overflow(x: u64, y: u64) -> (u64, bool); } -#[cfg(target_endian = "little")] pub fn to_le16(x: i16) -> i16 { x } -#[cfg(target_endian = "big")] pub fn to_le16(x: i16) -> i16 { unsafe { bswap16(x) } } -#[cfg(target_endian = "little")] pub fn to_le32(x: i32) -> i32 { x } -#[cfg(target_endian = "big")] pub fn to_le32(x: i32) -> i32 { unsafe { bswap32(x) } } -#[cfg(target_endian = "little")] pub fn to_le64(x: i64) -> i64 { x } -#[cfg(target_endian = "big")] pub fn to_le64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "little")] #[inline(always)] pub fn to_le16(x: i16) -> i16 { x } +#[cfg(target_endian = "big")] #[inline(always)] pub fn to_le16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "little")] #[inline(always)] pub fn to_le32(x: i32) -> i32 { x } +#[cfg(target_endian = "big")] #[inline(always)] pub fn to_le32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "little")] #[inline(always)] pub fn to_le64(x: i64) -> i64 { x } +#[cfg(target_endian = "big")] #[inline(always)] pub fn to_le64(x: i64) -> i64 { unsafe { bswap64(x) } } -#[cfg(target_endian = "little")] pub fn to_be16(x: i16) -> i16 { unsafe { bswap16(x) } } -#[cfg(target_endian = "big")] pub fn to_be16(x: i16) -> i16 { x } -#[cfg(target_endian = "little")] pub fn to_be32(x: i32) -> i32 { unsafe { bswap32(x) } } -#[cfg(target_endian = "big")] pub fn to_be32(x: i32) -> i32 { x } -#[cfg(target_endian = "little")] pub fn to_be64(x: i64) -> i64 { unsafe { bswap64(x) } } -#[cfg(target_endian = "big")] pub fn to_be64(x: i64) -> i64 { x } +#[cfg(target_endian = "little")] #[inline(always)] pub fn to_be16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "big")] #[inline(always)] pub fn to_be16(x: i16) -> i16 { x } +#[cfg(target_endian = "little")] #[inline(always)] pub fn to_be32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "big")] #[inline(always)] pub fn to_be32(x: i32) -> i32 { x } +#[cfg(target_endian = "little")] #[inline(always)] pub fn to_be64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "big")] #[inline(always)] pub fn to_be64(x: i64) -> i64 { x } -#[cfg(target_endian = "little")] pub fn from_le16(x: i16) -> i16 { x } -#[cfg(target_endian = "big")] pub fn from_le16(x: i16) -> i16 { unsafe { bswap16(x) } } -#[cfg(target_endian = "little")] pub fn from_le32(x: i32) -> i32 { x } -#[cfg(target_endian = "big")] pub fn from_le32(x: i32) -> i32 { unsafe { bswap32(x) } } -#[cfg(target_endian = "little")] pub fn from_le64(x: i64) -> i64 { x } -#[cfg(target_endian = "big")] pub fn from_le64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "little")] #[inline(always)] pub fn from_le16(x: i16) -> i16 { x } +#[cfg(target_endian = "big")] #[inline(always)] pub fn from_le16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "little")] #[inline(always)] pub fn from_le32(x: i32) -> i32 { x } +#[cfg(target_endian = "big")] #[inline(always)] pub fn from_le32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "little")] #[inline(always)] pub fn from_le64(x: i64) -> i64 { x } +#[cfg(target_endian = "big")] #[inline(always)] pub fn from_le64(x: i64) -> i64 { unsafe { bswap64(x) } } -#[cfg(target_endian = "little")] pub fn from_be16(x: i16) -> i16 { unsafe { bswap16(x) } } -#[cfg(target_endian = "big")] pub fn from_be16(x: i16) -> i16 { x } -#[cfg(target_endian = "little")] pub fn from_be32(x: i32) -> i32 { unsafe { bswap32(x) } } -#[cfg(target_endian = "big")] pub fn from_be32(x: i32) -> i32 { x } -#[cfg(target_endian = "little")] pub fn from_be64(x: i64) -> i64 { unsafe { bswap64(x) } } -#[cfg(target_endian = "big")] pub fn from_be64(x: i64) -> i64 { x } +#[cfg(target_endian = "little")] #[inline(always)] pub fn from_be16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "big")] #[inline(always)] pub fn from_be16(x: i16) -> i16 { x } +#[cfg(target_endian = "little")] #[inline(always)] pub fn from_be32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "big")] #[inline(always)] pub fn from_be32(x: i32) -> i32 { x } +#[cfg(target_endian = "little")] #[inline(always)] pub fn from_be64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "big")] #[inline(always)] pub fn from_be64(x: i64) -> i64 { x } /// `TypeId` represents a globally unique identifier for a type #[lang="type_id"] // This needs to be kept in lockstep with the code in trans/intrinsic.rs and From a82f32b3ebe712f6e67e2c17cb5920bde83bdb6f Mon Sep 17 00:00:00 2001 From: Carl-Anton Ingmarsson Date: Fri, 3 Jan 2014 00:28:17 +0100 Subject: [PATCH 3/3] fixup! libstd: Always inline all byteswap functions --- src/libstd/unstable/intrinsics.rs | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index bc88abaae973..9acc09dfcc68 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -486,33 +486,33 @@ extern "rust-intrinsic" { pub fn u64_mul_with_overflow(x: u64, y: u64) -> (u64, bool); } -#[cfg(target_endian = "little")] #[inline(always)] pub fn to_le16(x: i16) -> i16 { x } -#[cfg(target_endian = "big")] #[inline(always)] pub fn to_le16(x: i16) -> i16 { unsafe { bswap16(x) } } -#[cfg(target_endian = "little")] #[inline(always)] pub fn to_le32(x: i32) -> i32 { x } -#[cfg(target_endian = "big")] #[inline(always)] pub fn to_le32(x: i32) -> i32 { unsafe { bswap32(x) } } -#[cfg(target_endian = "little")] #[inline(always)] pub fn to_le64(x: i64) -> i64 { x } -#[cfg(target_endian = "big")] #[inline(always)] pub fn to_le64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "little")] #[inline] pub fn to_le16(x: i16) -> i16 { x } +#[cfg(target_endian = "big")] #[inline] pub fn to_le16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "little")] #[inline] pub fn to_le32(x: i32) -> i32 { x } +#[cfg(target_endian = "big")] #[inline] pub fn to_le32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "little")] #[inline] pub fn to_le64(x: i64) -> i64 { x } +#[cfg(target_endian = "big")] #[inline] pub fn to_le64(x: i64) -> i64 { unsafe { bswap64(x) } } -#[cfg(target_endian = "little")] #[inline(always)] pub fn to_be16(x: i16) -> i16 { unsafe { bswap16(x) } } -#[cfg(target_endian = "big")] #[inline(always)] pub fn to_be16(x: i16) -> i16 { x } -#[cfg(target_endian = "little")] #[inline(always)] pub fn to_be32(x: i32) -> i32 { unsafe { bswap32(x) } } -#[cfg(target_endian = "big")] #[inline(always)] pub fn to_be32(x: i32) -> i32 { x } -#[cfg(target_endian = "little")] #[inline(always)] pub fn to_be64(x: i64) -> i64 { unsafe { bswap64(x) } } -#[cfg(target_endian = "big")] #[inline(always)] pub fn to_be64(x: i64) -> i64 { x } +#[cfg(target_endian = "little")] #[inline] pub fn to_be16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "big")] #[inline] pub fn to_be16(x: i16) -> i16 { x } +#[cfg(target_endian = "little")] #[inline] pub fn to_be32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "big")] #[inline] pub fn to_be32(x: i32) -> i32 { x } +#[cfg(target_endian = "little")] #[inline] pub fn to_be64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "big")] #[inline] pub fn to_be64(x: i64) -> i64 { x } -#[cfg(target_endian = "little")] #[inline(always)] pub fn from_le16(x: i16) -> i16 { x } -#[cfg(target_endian = "big")] #[inline(always)] pub fn from_le16(x: i16) -> i16 { unsafe { bswap16(x) } } -#[cfg(target_endian = "little")] #[inline(always)] pub fn from_le32(x: i32) -> i32 { x } -#[cfg(target_endian = "big")] #[inline(always)] pub fn from_le32(x: i32) -> i32 { unsafe { bswap32(x) } } -#[cfg(target_endian = "little")] #[inline(always)] pub fn from_le64(x: i64) -> i64 { x } -#[cfg(target_endian = "big")] #[inline(always)] pub fn from_le64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "little")] #[inline] pub fn from_le16(x: i16) -> i16 { x } +#[cfg(target_endian = "big")] #[inline] pub fn from_le16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "little")] #[inline] pub fn from_le32(x: i32) -> i32 { x } +#[cfg(target_endian = "big")] #[inline] pub fn from_le32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "little")] #[inline] pub fn from_le64(x: i64) -> i64 { x } +#[cfg(target_endian = "big")] #[inline] pub fn from_le64(x: i64) -> i64 { unsafe { bswap64(x) } } -#[cfg(target_endian = "little")] #[inline(always)] pub fn from_be16(x: i16) -> i16 { unsafe { bswap16(x) } } -#[cfg(target_endian = "big")] #[inline(always)] pub fn from_be16(x: i16) -> i16 { x } -#[cfg(target_endian = "little")] #[inline(always)] pub fn from_be32(x: i32) -> i32 { unsafe { bswap32(x) } } -#[cfg(target_endian = "big")] #[inline(always)] pub fn from_be32(x: i32) -> i32 { x } -#[cfg(target_endian = "little")] #[inline(always)] pub fn from_be64(x: i64) -> i64 { unsafe { bswap64(x) } } -#[cfg(target_endian = "big")] #[inline(always)] pub fn from_be64(x: i64) -> i64 { x } +#[cfg(target_endian = "little")] #[inline] pub fn from_be16(x: i16) -> i16 { unsafe { bswap16(x) } } +#[cfg(target_endian = "big")] #[inline] pub fn from_be16(x: i16) -> i16 { x } +#[cfg(target_endian = "little")] #[inline] pub fn from_be32(x: i32) -> i32 { unsafe { bswap32(x) } } +#[cfg(target_endian = "big")] #[inline] pub fn from_be32(x: i32) -> i32 { x } +#[cfg(target_endian = "little")] #[inline] pub fn from_be64(x: i64) -> i64 { unsafe { bswap64(x) } } +#[cfg(target_endian = "big")] #[inline] pub fn from_be64(x: i64) -> i64 { x } /// `TypeId` represents a globally unique identifier for a type #[lang="type_id"] // This needs to be kept in lockstep with the code in trans/intrinsic.rs and