pub struct BackendDispatcher {
_private: (),
}
const PCIE_BANDWIDTH_GBPS: f64 = 32.0;
const MIN_GPU_DATA_SIZE_BYTES: usize = 10_000_000;
const GPU_THROUGHPUT_GFLOPS: f64 = 100.0;
const TRANSFER_OVERHEAD_MULTIPLIER: f64 = 5.0;
impl BackendDispatcher {
#[must_use]
#[allow(clippy::cast_precision_loss)]
pub fn select(total_bytes: usize, estimated_flops: f64) -> super::Backend {
if total_bytes < MIN_GPU_DATA_SIZE_BYTES {
return super::Backend::Simd;
}
let pcie_transfer_time_ms =
(total_bytes as f64 / (PCIE_BANDWIDTH_GBPS * 1_000_000_000.0)) * 1000.0;
let estimated_gpu_compute_ms =
(estimated_flops / (GPU_THROUGHPUT_GFLOPS * 1_000_000_000.0)) * 1000.0;
if estimated_gpu_compute_ms > pcie_transfer_time_ms * TRANSFER_OVERHEAD_MULTIPLIER {
super::Backend::Gpu
} else {
super::Backend::Simd
}
}
#[must_use]
#[allow(clippy::cast_precision_loss)]
pub const fn arithmetic_intensity(total_flops: f64, total_bytes: usize) -> f64 {
total_flops / total_bytes as f64
}
#[must_use]
#[allow(clippy::cast_precision_loss)]
pub const fn estimate_simple_aggregation_flops(num_elements: usize) -> f64 {
num_elements as f64
}
#[must_use]
#[allow(clippy::cast_precision_loss)]
pub const fn estimate_group_by_flops(num_elements: usize) -> f64 {
(num_elements as f64) * 6.0
}
#[must_use]
#[allow(clippy::cast_precision_loss)]
pub const fn estimate_filter_flops(num_elements: usize) -> f64 {
(num_elements as f64) * 2.0
}
#[must_use]
#[allow(clippy::cast_precision_loss)]
pub const fn estimate_join_flops(left_size: usize, right_size: usize) -> f64 {
((left_size + right_size) as f64) * 5.0
}
}