Benchmarking
বেঞ্চমার্কিং
একটা performance দাবিকে প্রতিরক্ষাযোগ্য করার নিয়মশৃঙ্খলা — warm-up, একাধিক run, percentile রিপোর্টিং, noise নিয়ন্ত্রণ, আর compiler-এর dead-code elimination ঠেকানো।
also: microbenchmark
একটা সঠিক microbenchmark-এর চেকলিস্ট, প্রতিটা লাইন একটা বাস্তব ব্যর্থতার প্রতিকার:
- Warm-up আলাদা করা — JIT compilation, cache warming, CPU frequency ramp-up প্রথম কয়েক run-কে বিভ্রান্তিকর করে; সেগুলো বাতিল করে measured phase আলাদা রাখা।
- Wall-clock বনাম CPU time — user-perceived latency মাপতে wall-clock, resource খরচ মাপতে CPU time; I/O-bound কাজে দুইটা ব্যাপকভাবে ভিন্ন হতে পারে।
- Median, mean না — outlier (GC pause, background process) mean-কে বিকৃত করে; median resistant।
- Percentile (
p95/p99) — tail latency প্রায়ই average-এর চেয়ে বেশি গুরুত্বপূর্ণ, বিশেষত distributed system-এ (Dean ও Barroso, “The Tail at Scale”)। - Confidence interval —
mean ± 1.96 × stddev/√n(95%); দুইটা version-এর CI overlap করলে “A দ্রুত” দাবি করা অনিরাপদ। - Noise নিয়ন্ত্রণ —
taskset/CPU pinning,numactlদিয়ে NUMA placement, thermal throttling monitor।
সবচেয়ে বিপজ্জনক ভুল — dead-code elimination। ফলাফল ব্যবহার না
হলে -O2 পুরো benchmark loop মুছে দিতে পারে, measured time শূন্যের
কাছে নেমে আসে। প্রতিকার — output (আর প্রয়োজনে input) কে opaque করে
রাখা:
let result = std::hint::black_box(compute(std::hint::black_box(x)));
C/C++-এ সমতুল্য: asm volatile("" : : "r"(x) : "memory") বা Google
Benchmark-এর DoNotOptimize()।