[07_weird_assembly_machine] add a faster implementation of func0
This commit is contained in:
2
.cargo/config.toml
Normal file
2
.cargo/config.toml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[target.x86_64-unknown-linux-gnu]
|
||||||
|
rustflags = ["-Ctarget-cpu=native"]
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
use lib::compute_async;
|
use lib::compute_async;
|
||||||
|
|
||||||
// https://button.qedaka.de/07_weird_assembly_machine.html?name=Jonah&n=10000000000000070&x=4410539207075887818
|
// https://button.qedaka.de/07_weird_assembly_machine.html?name=Jonah&n=10000000000000070&x=4410539207075887818
|
||||||
@@ -68,8 +69,8 @@ const DATA: &[u64] = &[
|
|||||||
11796026101712826135, 2668163399826034890, 1114227485540495868, 12046048025420064663,
|
11796026101712826135, 2668163399826034890, 1114227485540495868, 12046048025420064663,
|
||||||
];
|
];
|
||||||
|
|
||||||
const N: u64 = 10000000047000070;
|
const N: u64 = 10000045930000000;
|
||||||
const X: u64 = 2925478411027973783;
|
const X: u64 = 16195396392266746892;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
compute_async(|tx| {
|
compute_async(|tx| {
|
||||||
@@ -86,16 +87,6 @@ fn main() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn func0(a: u64, mut b: u64) -> u64 {
|
|
||||||
let mut x: u64 = 0;
|
|
||||||
while b != 0 {
|
|
||||||
let c = b.trailing_zeros();
|
|
||||||
b = b ^ 1u64.rotate_left(c);
|
|
||||||
x = x ^ a.rotate_left(c);
|
|
||||||
}
|
|
||||||
x
|
|
||||||
}
|
|
||||||
|
|
||||||
fn func1(x: u64, mut n: u64) -> u64 {
|
fn func1(x: u64, mut n: u64) -> u64 {
|
||||||
let x = func2(x, &DATA[0..128]);
|
let x = func2(x, &DATA[0..128]);
|
||||||
if x <= n {
|
if x <= n {
|
||||||
@@ -112,6 +103,32 @@ fn func2(x: u64, data: &[u64]) -> u64 {
|
|||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(all(target_arch = "x86_64", target_feature = "pclmulqdq")))]
|
||||||
|
fn func0(a: u64, mut b: u64) -> u64 {
|
||||||
|
let mut x: u64 = 0;
|
||||||
|
while b != 0 {
|
||||||
|
let c = b.trailing_zeros();
|
||||||
|
b = b ^ 1u64.rotate_left(c);
|
||||||
|
x = x ^ a.rotate_left(c);
|
||||||
|
}
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "x86_64", target_feature = "pclmulqdq"))]
|
||||||
|
fn func0(a: u64, b: u64) -> u64 {
|
||||||
|
use std::arch::x86_64::*;
|
||||||
|
unsafe {
|
||||||
|
let a_vec = _mm_set_epi64x(0, a as i64);
|
||||||
|
let b_vec = _mm_set_epi64x(0, b as i64);
|
||||||
|
let result = _mm_clmulepi64_si128(a_vec, b_vec, 0x00);
|
||||||
|
|
||||||
|
// Extract both 64-bit halves and XOR them
|
||||||
|
let low = _mm_extract_epi64(result, 0) as u64;
|
||||||
|
let high = _mm_extract_epi64(result, 1) as u64;
|
||||||
|
low ^ high
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user