Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,152 @@
|
||||
fn fault() -> Fault {
|
||||
&FaultInfo {
|
||||
message: "integer arithmetic fault",
|
||||
source: "reference.dever",
|
||||
line: 1,
|
||||
column: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn map_reference(values: &[i64]) -> Result<Vec<i64>, Fault> {
|
||||
let mut output = Vec::with_capacity(values.len());
|
||||
for value in values {
|
||||
output.push(value.checked_add(1).ok_or_else(fault)?);
|
||||
}
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
fn total_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
let adjusted = value.checked_add(1).ok_or_else(fault)?;
|
||||
total = total.checked_add(adjusted).ok_or_else(fault)?;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
// 与跨包调用一致,投影失败和累计失败必须能定位到不同来源。
|
||||
fn total_reference_distinct_faults(values: &[i64]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
let adjusted = value.checked_add(1).ok_or(&FaultInfo {
|
||||
message: "integer arithmetic fault",
|
||||
source: "reference/value.rs",
|
||||
line: 1,
|
||||
column: 1,
|
||||
})?;
|
||||
total = total.checked_add(adjusted).ok_or(&FaultInfo {
|
||||
message: "integer arithmetic fault",
|
||||
source: "reference/batch.rs",
|
||||
line: 2,
|
||||
column: 1,
|
||||
})?;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn dispatch_generated(values: &[i64]) -> Result<i64, Fault> {
|
||||
GENERATED_DISPATCH(values.first().copied().unwrap_or(0))
|
||||
}
|
||||
|
||||
fn dispatch_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
values
|
||||
.first()
|
||||
.copied()
|
||||
.unwrap_or(0)
|
||||
.checked_mul(2)
|
||||
.ok_or_else(fault)
|
||||
}
|
||||
|
||||
fn dispatch_total_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
let doubled = value.checked_mul(2).ok_or_else(fault)?;
|
||||
total = total.checked_add(doubled).ok_or(&FaultInfo {
|
||||
message: "integer overflow",
|
||||
source: "reference/dispatch.rs",
|
||||
line: 2,
|
||||
column: 1,
|
||||
})?;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let values: Vec<i64> = (0..1024).map(|value| value % 17).collect();
|
||||
for values in [&[i64::MAX][..], &[i64::MAX - 1, 1][..], &[i64::MIN][..]] {
|
||||
assert_eq!(
|
||||
GENERATED_MAP(values).map_err(|_| ()),
|
||||
map_reference(values).map_err(|_| ())
|
||||
);
|
||||
assert_eq!(
|
||||
GENERATED_TOTAL(values).map_err(|_| ()),
|
||||
total_reference(values).map_err(|_| ())
|
||||
);
|
||||
assert_eq!(
|
||||
GENERATED_TOTAL(values).map_err(|fault| fault.message),
|
||||
total_reference_distinct_faults(values).map_err(|fault| fault.message)
|
||||
);
|
||||
assert_eq!(
|
||||
dispatch_generated(values).map_err(|_| ()),
|
||||
dispatch_reference(values).map_err(|_| ())
|
||||
);
|
||||
}
|
||||
let projection = GENERATED_TOTAL(&[i64::MAX]).unwrap_err();
|
||||
let sum = GENERATED_TOTAL(&[i64::MAX - 1, 1]).unwrap_err();
|
||||
assert_ne!(projection.source, sum.source);
|
||||
assert_ne!(
|
||||
total_reference_distinct_faults(&[i64::MAX])
|
||||
.unwrap_err()
|
||||
.source,
|
||||
total_reference_distinct_faults(&[i64::MAX - 1, 1])
|
||||
.unwrap_err()
|
||||
.source
|
||||
);
|
||||
for values in [&[i64::MAX][..], &[i64::MAX / 2, 1][..], &[i64::MIN][..]] {
|
||||
assert_eq!(
|
||||
GENERATED_DISPATCH_TOTAL(values).map_err(|fault| fault.message),
|
||||
dispatch_total_reference(values).map_err(|fault| fault.message)
|
||||
);
|
||||
}
|
||||
println!("case,sample,implementation,elapsed_ns,checksum");
|
||||
compare(
|
||||
"package_map",
|
||||
&values,
|
||||
20000,
|
||||
GENERATED_MAP,
|
||||
map_reference,
|
||||
|value| value.iter().map(|value| *value as u64).sum(),
|
||||
);
|
||||
compare(
|
||||
"package_total",
|
||||
&values,
|
||||
20000,
|
||||
GENERATED_TOTAL,
|
||||
total_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"package_total_distinct_faults",
|
||||
&values,
|
||||
20000,
|
||||
GENERATED_TOTAL,
|
||||
total_reference_distinct_faults,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"package_dispatch",
|
||||
&[21],
|
||||
3000000,
|
||||
dispatch_generated,
|
||||
dispatch_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"package_dispatch_batch",
|
||||
&values,
|
||||
20000,
|
||||
GENERATED_DISPATCH_TOTAL,
|
||||
dispatch_total_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
// 隔离同一受检翻倍在内联表达式、Rust 函数边界和 Dever 生成路径上的差异。
|
||||
// 共享故障元数据以排除错误对象大小和来源内容,原 packages 参照保持不变。
|
||||
|
||||
fn shared_fault() -> Fault {
|
||||
GENERATED_DISPATCH(i64::MAX).unwrap_err()
|
||||
}
|
||||
|
||||
fn dispatch_generated(values: &[i64]) -> Result<i64, Fault> {
|
||||
GENERATED_DISPATCH(values.first().copied().unwrap_or(0))
|
||||
}
|
||||
|
||||
fn adjust_generated(values: &[i64]) -> Result<i64, Fault> {
|
||||
GENERATED_ADJUST(values.first().copied().unwrap_or(0))
|
||||
}
|
||||
|
||||
fn inline_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
values
|
||||
.first()
|
||||
.copied()
|
||||
.unwrap_or(0)
|
||||
.checked_mul(2)
|
||||
.ok_or_else(shared_fault)
|
||||
}
|
||||
|
||||
fn propagated_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
let answer = values
|
||||
.first()
|
||||
.copied()
|
||||
.unwrap_or(0)
|
||||
.checked_mul(2)
|
||||
.ok_or_else(shared_fault)?;
|
||||
Ok(answer)
|
||||
}
|
||||
|
||||
fn helper(value: i64) -> Result<i64, Fault> {
|
||||
value.checked_mul(2).ok_or_else(shared_fault)
|
||||
}
|
||||
|
||||
fn helper_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
helper(values.first().copied().unwrap_or(0))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn early_helper(value: i64) -> Result<i64, Fault> {
|
||||
value.checked_mul(2).ok_or_else(shared_fault)
|
||||
}
|
||||
|
||||
fn early_helper_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
early_helper(values.first().copied().unwrap_or(0))
|
||||
}
|
||||
|
||||
fn independent_helper(value: i64) -> Result<i64, Fault> {
|
||||
value.checked_mul(2).ok_or(&FaultInfo {
|
||||
message: "integer arithmetic fault",
|
||||
source: "reference.dever",
|
||||
line: 1,
|
||||
column: 1,
|
||||
})
|
||||
}
|
||||
|
||||
fn independent_helper_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
independent_helper(values.first().copied().unwrap_or(0))
|
||||
}
|
||||
|
||||
fn propagated_helper(value: i64) -> Result<i64, Fault> {
|
||||
let answer = value.checked_mul(2).ok_or_else(shared_fault)?;
|
||||
Ok(answer)
|
||||
}
|
||||
|
||||
fn propagated_helper_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
propagated_helper(values.first().copied().unwrap_or(0))
|
||||
}
|
||||
|
||||
fn batch_generated(values: &[i64]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
total = total
|
||||
.checked_add(GENERATED_DISPATCH(*value)?)
|
||||
.ok_or_else(shared_fault)?;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn batch_reference(values: &[i64]) -> Result<i64, Fault> {
|
||||
let mut total = 0i64;
|
||||
for value in values {
|
||||
let doubled = value.checked_mul(2).ok_or_else(shared_fault)?;
|
||||
total = total.checked_add(doubled).ok_or_else(shared_fault)?;
|
||||
}
|
||||
Ok(total)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let operations = [
|
||||
dispatch_generated as fn(&[i64]) -> Result<i64, Fault>,
|
||||
adjust_generated,
|
||||
inline_reference,
|
||||
propagated_reference,
|
||||
helper_reference,
|
||||
early_helper_reference,
|
||||
propagated_helper_reference,
|
||||
];
|
||||
for value in [
|
||||
i64::MIN,
|
||||
i64::MIN / 2 - 1,
|
||||
i64::MIN / 2,
|
||||
-1,
|
||||
0,
|
||||
1,
|
||||
21,
|
||||
i64::MAX / 2,
|
||||
i64::MAX / 2 + 1,
|
||||
i64::MAX,
|
||||
] {
|
||||
for operation in operations {
|
||||
assert_eq!(
|
||||
operation(&[value]).map_err(|fault| fault.to_string()),
|
||||
inline_reference(&[value]).map_err(|fault| fault.to_string())
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
independent_helper_reference(&[value]).map_err(|_| ()),
|
||||
inline_reference(&[value]).map_err(|_| ())
|
||||
);
|
||||
}
|
||||
for (name, operation) in [
|
||||
(
|
||||
"dispatch",
|
||||
dispatch_generated as fn(&[i64]) -> Result<i64, Fault>,
|
||||
),
|
||||
("adjust", adjust_generated),
|
||||
("propagated", propagated_reference),
|
||||
("helper", helper_reference),
|
||||
("early_helper", early_helper_reference),
|
||||
("independent_helper", independent_helper_reference),
|
||||
("propagated_helper", propagated_helper_reference),
|
||||
] {
|
||||
eprintln!(
|
||||
"{name}_equals_dispatch={}",
|
||||
std::ptr::fn_addr_eq(
|
||||
operation,
|
||||
dispatch_generated as fn(&[i64]) -> Result<i64, Fault>
|
||||
)
|
||||
);
|
||||
}
|
||||
let values = (0..256).map(|index| index * 17 - 2000).collect::<Vec<_>>();
|
||||
for input in [
|
||||
vec![],
|
||||
vec![i64::MAX],
|
||||
vec![i64::MIN],
|
||||
vec![i64::MAX / 2, 1],
|
||||
values.clone(),
|
||||
] {
|
||||
assert_eq!(
|
||||
batch_generated(&input).map_err(|fault| fault.to_string()),
|
||||
batch_reference(&input).map_err(|fault| fault.to_string())
|
||||
);
|
||||
}
|
||||
println!("case,sample,implementation,elapsed_ns,checksum");
|
||||
compare(
|
||||
"scalar_matched_hot_path",
|
||||
&[21],
|
||||
3000000,
|
||||
adjust_generated,
|
||||
independent_helper_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"scalar_inline",
|
||||
&[21],
|
||||
3000000,
|
||||
dispatch_generated,
|
||||
inline_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare_named(
|
||||
"scalar_direct",
|
||||
&[21],
|
||||
3000000,
|
||||
dispatch_generated,
|
||||
adjust_generated,
|
||||
|value| *value as u64,
|
||||
"direct",
|
||||
);
|
||||
compare(
|
||||
"scalar_propagated",
|
||||
&[21],
|
||||
3000000,
|
||||
dispatch_generated,
|
||||
propagated_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"scalar_helper",
|
||||
&[21],
|
||||
3000000,
|
||||
dispatch_generated,
|
||||
helper_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"scalar_early_helper",
|
||||
&[21],
|
||||
3000000,
|
||||
dispatch_generated,
|
||||
early_helper_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"scalar_independent_helper",
|
||||
&[21],
|
||||
3000000,
|
||||
dispatch_generated,
|
||||
independent_helper_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"scalar_propagated_helper",
|
||||
&[21],
|
||||
3000000,
|
||||
dispatch_generated,
|
||||
propagated_helper_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
compare(
|
||||
"scalar_batch",
|
||||
&values,
|
||||
30000,
|
||||
batch_generated,
|
||||
batch_reference,
|
||||
|value| *value as u64,
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user