From a7d45665dabb8d795a8dccabc241af7a8c0271b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=5BQuy=20Anh=5D=20=C2=ABElliot=C2=BB=20Nguyen?= <23906-nguyenquy@users.noreply.gitlab.inf.ethz.ch> Date: Wed, 17 Jun 2026 07:28:11 +0200 Subject: [PATCH] Flop Count Calculations + x86 Measurements + c13 Fix --- headers/constants.hpp | 15 + headers/constants_float.hpp | 27 +- measurements/memory/x86/1.log | 24 +- measurements/memory/x86/10.log | 37 + measurements/memory/x86/100.log | 37 + measurements/memory/x86/11.log | 37 + measurements/memory/x86/12.log | 37 + measurements/memory/x86/13.log | 37 + measurements/memory/x86/14.log | 37 + measurements/memory/x86/15.log | 37 + measurements/memory/x86/16.log | 37 + measurements/memory/x86/17.log | 37 + measurements/memory/x86/18.log | 37 + measurements/memory/x86/19.log | 37 + measurements/memory/x86/2.log | 24 +- measurements/memory/x86/20.log | 37 + measurements/memory/x86/21.log | 37 + measurements/memory/x86/22.log | 37 + measurements/memory/x86/23.log | 37 + measurements/memory/x86/24.log | 37 + measurements/memory/x86/25.log | 37 + measurements/memory/x86/26.log | 37 + measurements/memory/x86/27.log | 37 + measurements/memory/x86/28.log | 37 + measurements/memory/x86/29.log | 37 + measurements/memory/x86/3.log | 24 +- measurements/memory/x86/30.log | 37 + measurements/memory/x86/31.log | 37 + measurements/memory/x86/32.log | 37 + measurements/memory/x86/33.log | 37 + measurements/memory/x86/34.log | 37 + measurements/memory/x86/35.log | 37 + measurements/memory/x86/36.log | 37 + measurements/memory/x86/37.log | 37 + measurements/memory/x86/38.log | 37 + measurements/memory/x86/39.log | 37 + measurements/memory/x86/4.log | 37 + measurements/memory/x86/40.log | 37 + measurements/memory/x86/41.log | 37 + measurements/memory/x86/42.log | 37 + measurements/memory/x86/43.log | 37 + measurements/memory/x86/44.log | 37 + measurements/memory/x86/45.log | 37 + measurements/memory/x86/46.log | 37 + measurements/memory/x86/47.log | 37 + measurements/memory/x86/48.log | 37 + measurements/memory/x86/49.log | 37 + measurements/memory/x86/5.log | 37 + measurements/memory/x86/50.log | 37 + measurements/memory/x86/51.log | 37 + measurements/memory/x86/52.log | 37 + measurements/memory/x86/53.log | 37 + measurements/memory/x86/54.log | 37 + measurements/memory/x86/55.log | 37 + measurements/memory/x86/56.log | 37 + measurements/memory/x86/57.log | 37 + measurements/memory/x86/58.log | 37 + measurements/memory/x86/59.log | 37 + measurements/memory/x86/6.log | 37 + measurements/memory/x86/60.log | 37 + measurements/memory/x86/61.log | 37 + measurements/memory/x86/62.log | 37 + measurements/memory/x86/63.log | 37 + measurements/memory/x86/64.log | 37 + measurements/memory/x86/65.log | 37 + measurements/memory/x86/66.log | 37 + measurements/memory/x86/67.log | 37 + measurements/memory/x86/68.log | 37 + measurements/memory/x86/69.log | 37 + measurements/memory/x86/7.log | 37 + measurements/memory/x86/70.log | 37 + measurements/memory/x86/71.log | 37 + measurements/memory/x86/72.log | 37 + measurements/memory/x86/73.log | 37 + measurements/memory/x86/74.log | 37 + measurements/memory/x86/75.log | 37 + measurements/memory/x86/76.log | 37 + measurements/memory/x86/77.log | 37 + measurements/memory/x86/78.log | 37 + measurements/memory/x86/79.log | 37 + measurements/memory/x86/8.log | 37 + measurements/memory/x86/80.log | 37 + measurements/memory/x86/81.log | 37 + measurements/memory/x86/82.log | 37 + measurements/memory/x86/83.log | 37 + measurements/memory/x86/84.log | 37 + measurements/memory/x86/85.log | 37 + measurements/memory/x86/86.log | 37 + measurements/memory/x86/87.log | 37 + measurements/memory/x86/88.log | 37 + measurements/memory/x86/89.log | 37 + measurements/memory/x86/9.log | 37 + measurements/memory/x86/90.log | 37 + measurements/memory/x86/91.log | 37 + measurements/memory/x86/92.log | 37 + measurements/memory/x86/93.log | 37 + measurements/memory/x86/94.log | 37 + measurements/memory/x86/95.log | 37 + measurements/memory/x86/96.log | 37 + measurements/memory/x86/97.log | 37 + measurements/memory/x86/98.log | 37 + measurements/memory/x86/99.log | 37 + measurements/variant_baseline/x86/3.log | 58 ++ measurements/variant_branchless/x86/2.log | 58 ++ measurements/variant_branchless/x86/3.log | 58 ++ .../variant_branchless_sqrtfree/x86/2.log | 58 ++ .../variant_branchless_sqrtfree/x86/3.log | 58 ++ measurements/variant_cutoff/x86/2.log | 58 ++ measurements/variant_cutoff/x86/3.log | 58 ++ .../variant_cutoff_callsite/x86/2.log | 58 ++ .../variant_cutoff_callsite/x86/3.log | 58 ++ measurements/variant_float_baseline/x86/2.log | 58 ++ measurements/variant_float_baseline/x86/3.log | 58 ++ measurements/variant_float_inlining/x86/2.log | 58 ++ measurements/variant_float_inlining/x86/3.log | 58 ++ .../variant_float_inlining_SoA/x86/2.log | 58 ++ .../variant_float_inlining_SoA/x86/3.log | 58 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 64 ++ .../x86/1.log | 66 ++ .../x86/2.log | 64 ++ .../x86/3.log | 64 ++ .../x86/1.log | 66 ++ .../x86/2.log | 64 ++ .../x86/3.log | 64 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 64 ++ .../x86/3.log | 64 ++ .../x86/1.log | 66 ++ .../x86/2.log | 64 ++ .../x86/3.log | 64 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/2.log | 58 ++ .../x86/3.log | 58 ++ .../x86/2.log | 58 ++ .../x86/3.log | 58 ++ .../x86/2.log | 58 ++ .../x86/3.log | 58 ++ .../x86/2.log | 58 ++ .../x86/3.log | 58 ++ .../x86/2.log | 58 ++ .../x86/3.log | 58 ++ measurements/variant_inlining_7/x86/2.log | 58 ++ measurements/variant_inlining_7/x86/3.log | 58 ++ measurements/variant_inlining_7_SoA/x86/2.log | 58 ++ measurements/variant_inlining_7_SoA/x86/3.log | 58 ++ .../variant_inlining_7_SoA_AVX2/x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 64 ++ .../x86/3.log | 64 ++ .../variant_inlining_7_symmetry_1/x86/2.log | 58 ++ .../variant_inlining_7_symmetry_1/x86/3.log | 58 ++ .../variant_inlining_7_symmetry_2/x86/2.log | 58 ++ .../variant_inlining_7_symmetry_2/x86/3.log | 58 ++ .../x86/2.log | 58 ++ .../x86/3.log | 58 ++ .../x86/2.log | 58 ++ .../x86/3.log | 58 ++ measurements/variant_inlining_8/x86/2.log | 58 ++ measurements/variant_inlining_8/x86/3.log | 58 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ .../x86/1.log | 66 ++ .../x86/2.log | 66 ++ .../x86/3.log | 66 ++ measurements/variant_lut_exp/x86/2.log | 58 ++ measurements/variant_lut_exp/x86/3.log | 58 ++ scripts/mem-bench.sh | 12 +- variants/variant_AVX512_1_flopcount.cpp | 568 ++++++++++++++ variants/variant_baseline_flopcount.cpp | 440 +++++++++++ variants/variant_float_baseline_flopcount.cpp | 438 +++++++++++ ...float_inlining_SoA_AVX2_polyexp_expfix.cpp | 3 +- ...inlining_SoA_AVX2_polyexp_rsqrt_expfix.cpp | 3 +- ..._SoA_AVX2_polyexp_rsqrt_loopopt_expfix.cpp | 3 +- ...oat_inlining_SoA_AVX512_polyexp_expfix.cpp | 540 +++++++++++++ ..._SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp | 557 +++++++++++++ ...ning_SoA_AVX512_polyexp_moreavx_expfix.cpp | 577 ++++++++++++++ ...oA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp | 638 +++++++++++++++ ...2_polyexp_moreavx_ilp_2_moreilp_expfix.cpp | 735 ++++++++++++++++++ ...512_polyexp_moreavx_ilp_2_rsqrt_expfix.cpp | 634 +++++++++++++++ ...p_moreavx_ilp_2_rsqrt_morersqrt_expfix.cpp | 206 ++--- ..._ilp_2_rsqrt_morersqrt_expfix_improved.cpp | 3 +- ...sqrt_morersqrt_expfix_improved_moreilp.cpp | 3 +- ...oA_AVX512_polyexp_moreavx_ilp_4_expfix.cpp | 727 +++++++++++++++++ .../variant_float_inlining_SoA_flopcount.cpp | 380 +++++++++ variants/variant_float_inlining_flopcount.cpp | 366 +++++++++ ...ant_inlining_7_SoA_AVX2_polyexp_expfix.cpp | 30 +- variants/variant_inlining_7_SoA_flopcount.cpp | 362 +++++++++ variants/variant_inlining_7_flopcount.cpp | 352 +++++++++ ..._SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp | 483 ++++++++++++ ...A_AVX512_polyexp_fastinvsqrt_sr_expfix.cpp | 576 ++++++++++++++ ...ng_8_SoA_AVX512_polyexp_moreavx_expfix.cpp | 563 ++++++++++++++ ...oA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp | 640 +++++++++++++++ variants/variant_inlining_8_flopcount.cpp | 343 ++++++++ 225 files changed, 19699 insertions(+), 172 deletions(-) create mode 100644 measurements/memory/x86/10.log create mode 100644 measurements/memory/x86/100.log create mode 100644 measurements/memory/x86/11.log create mode 100644 measurements/memory/x86/12.log create mode 100644 measurements/memory/x86/13.log create mode 100644 measurements/memory/x86/14.log create mode 100644 measurements/memory/x86/15.log create mode 100644 measurements/memory/x86/16.log create mode 100644 measurements/memory/x86/17.log create mode 100644 measurements/memory/x86/18.log create mode 100644 measurements/memory/x86/19.log create mode 100644 measurements/memory/x86/20.log create mode 100644 measurements/memory/x86/21.log create mode 100644 measurements/memory/x86/22.log create mode 100644 measurements/memory/x86/23.log create mode 100644 measurements/memory/x86/24.log create mode 100644 measurements/memory/x86/25.log create mode 100644 measurements/memory/x86/26.log create mode 100644 measurements/memory/x86/27.log create mode 100644 measurements/memory/x86/28.log create mode 100644 measurements/memory/x86/29.log create mode 100644 measurements/memory/x86/30.log create mode 100644 measurements/memory/x86/31.log create mode 100644 measurements/memory/x86/32.log create mode 100644 measurements/memory/x86/33.log create mode 100644 measurements/memory/x86/34.log create mode 100644 measurements/memory/x86/35.log create mode 100644 measurements/memory/x86/36.log create mode 100644 measurements/memory/x86/37.log create mode 100644 measurements/memory/x86/38.log create mode 100644 measurements/memory/x86/39.log create mode 100644 measurements/memory/x86/4.log create mode 100644 measurements/memory/x86/40.log create mode 100644 measurements/memory/x86/41.log create mode 100644 measurements/memory/x86/42.log create mode 100644 measurements/memory/x86/43.log create mode 100644 measurements/memory/x86/44.log create mode 100644 measurements/memory/x86/45.log create mode 100644 measurements/memory/x86/46.log create mode 100644 measurements/memory/x86/47.log create mode 100644 measurements/memory/x86/48.log create mode 100644 measurements/memory/x86/49.log create mode 100644 measurements/memory/x86/5.log create mode 100644 measurements/memory/x86/50.log create mode 100644 measurements/memory/x86/51.log create mode 100644 measurements/memory/x86/52.log create mode 100644 measurements/memory/x86/53.log create mode 100644 measurements/memory/x86/54.log create mode 100644 measurements/memory/x86/55.log create mode 100644 measurements/memory/x86/56.log create mode 100644 measurements/memory/x86/57.log create mode 100644 measurements/memory/x86/58.log create mode 100644 measurements/memory/x86/59.log create mode 100644 measurements/memory/x86/6.log create mode 100644 measurements/memory/x86/60.log create mode 100644 measurements/memory/x86/61.log create mode 100644 measurements/memory/x86/62.log create mode 100644 measurements/memory/x86/63.log create mode 100644 measurements/memory/x86/64.log create mode 100644 measurements/memory/x86/65.log create mode 100644 measurements/memory/x86/66.log create mode 100644 measurements/memory/x86/67.log create mode 100644 measurements/memory/x86/68.log create mode 100644 measurements/memory/x86/69.log create mode 100644 measurements/memory/x86/7.log create mode 100644 measurements/memory/x86/70.log create mode 100644 measurements/memory/x86/71.log create mode 100644 measurements/memory/x86/72.log create mode 100644 measurements/memory/x86/73.log create mode 100644 measurements/memory/x86/74.log create mode 100644 measurements/memory/x86/75.log create mode 100644 measurements/memory/x86/76.log create mode 100644 measurements/memory/x86/77.log create mode 100644 measurements/memory/x86/78.log create mode 100644 measurements/memory/x86/79.log create mode 100644 measurements/memory/x86/8.log create mode 100644 measurements/memory/x86/80.log create mode 100644 measurements/memory/x86/81.log create mode 100644 measurements/memory/x86/82.log create mode 100644 measurements/memory/x86/83.log create mode 100644 measurements/memory/x86/84.log create mode 100644 measurements/memory/x86/85.log create mode 100644 measurements/memory/x86/86.log create mode 100644 measurements/memory/x86/87.log create mode 100644 measurements/memory/x86/88.log create mode 100644 measurements/memory/x86/89.log create mode 100644 measurements/memory/x86/9.log create mode 100644 measurements/memory/x86/90.log create mode 100644 measurements/memory/x86/91.log create mode 100644 measurements/memory/x86/92.log create mode 100644 measurements/memory/x86/93.log create mode 100644 measurements/memory/x86/94.log create mode 100644 measurements/memory/x86/95.log create mode 100644 measurements/memory/x86/96.log create mode 100644 measurements/memory/x86/97.log create mode 100644 measurements/memory/x86/98.log create mode 100644 measurements/memory/x86/99.log create mode 100644 measurements/variant_baseline/x86/3.log create mode 100644 measurements/variant_branchless/x86/2.log create mode 100644 measurements/variant_branchless/x86/3.log create mode 100644 measurements/variant_branchless_sqrtfree/x86/2.log create mode 100644 measurements/variant_branchless_sqrtfree/x86/3.log create mode 100644 measurements/variant_cutoff/x86/2.log create mode 100644 measurements/variant_cutoff/x86/3.log create mode 100644 measurements/variant_cutoff_callsite/x86/2.log create mode 100644 measurements/variant_cutoff_callsite/x86/3.log create mode 100644 measurements/variant_float_baseline/x86/2.log create mode 100644 measurements/variant_float_baseline/x86/3.log create mode 100644 measurements/variant_float_inlining/x86/2.log create mode 100644 measurements/variant_float_inlining/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/1.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry_ILP_16/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry_ILP_16/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry_ILP_2/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry_ILP_2/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry_ILP_4/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry_ILP_4/x86/3.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry_ILP_8/x86/2.log create mode 100644 measurements/variant_float_inlining_SoA_symmetry_ILP_8/x86/3.log create mode 100644 measurements/variant_inlining_7/x86/2.log create mode 100644 measurements/variant_inlining_7/x86/3.log create mode 100644 measurements/variant_inlining_7_SoA/x86/2.log create mode 100644 measurements/variant_inlining_7_SoA/x86/3.log create mode 100644 measurements/variant_inlining_7_SoA_AVX2/x86/3.log create mode 100644 measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/1.log create mode 100644 measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/2.log create mode 100644 measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/3.log create mode 100644 measurements/variant_inlining_7_symmetry_1/x86/2.log create mode 100644 measurements/variant_inlining_7_symmetry_1/x86/3.log create mode 100644 measurements/variant_inlining_7_symmetry_2/x86/2.log create mode 100644 measurements/variant_inlining_7_symmetry_2/x86/3.log create mode 100644 measurements/variant_inlining_7_symmetry_2_ilp_1/x86/2.log create mode 100644 measurements/variant_inlining_7_symmetry_2_ilp_1/x86/3.log create mode 100644 measurements/variant_inlining_7_symmetry_2_ilp_2/x86/2.log create mode 100644 measurements/variant_inlining_7_symmetry_2_ilp_2/x86/3.log create mode 100644 measurements/variant_inlining_8/x86/2.log create mode 100644 measurements/variant_inlining_8/x86/3.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/1.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/2.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/3.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/1.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/2.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/3.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/1.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/2.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/3.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/1.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/2.log create mode 100644 measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/3.log create mode 100644 measurements/variant_lut_exp/x86/2.log create mode 100644 measurements/variant_lut_exp/x86/3.log create mode 100644 variants/variant_AVX512_1_flopcount.cpp create mode 100644 variants/variant_baseline_flopcount.cpp create mode 100644 variants/variant_float_baseline_flopcount.cpp create mode 100644 variants/variant_float_inlining_SoA_AVX512_polyexp_expfix.cpp create mode 100644 variants/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp create mode 100644 variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix.cpp create mode 100644 variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp create mode 100644 variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix.cpp create mode 100644 variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix.cpp create mode 100644 variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix.cpp create mode 100644 variants/variant_float_inlining_SoA_flopcount.cpp create mode 100644 variants/variant_float_inlining_flopcount.cpp create mode 100644 variants/variant_inlining_7_SoA_flopcount.cpp create mode 100644 variants/variant_inlining_7_flopcount.cpp create mode 100644 variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp create mode 100644 variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix.cpp create mode 100644 variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix.cpp create mode 100644 variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp create mode 100644 variants/variant_inlining_8_flopcount.cpp diff --git a/headers/constants.hpp b/headers/constants.hpp index ce3c51f..cc7c343 100644 --- a/headers/constants.hpp +++ b/headers/constants.hpp @@ -117,3 +117,18 @@ const double CUTOFF_SQ = CUTOFF * CUTOFF; const double cos_phi_sq = cos_phi * cos_phi; const size_t CACHE_BLOCK_SIZE = std::hardware_destructive_interference_size; + +const double c0_scalar = 1.0 / 1; +const double c1_scalar = 1.0 / 1; +const double c2_scalar = 1.0 / 2; +const double c3_scalar = 1.0 / 6; +const double c4_scalar = 1.0 / 24; +const double c5_scalar = 1.0 / 120; +const double c6_scalar = 1.0 / 720; +const double c7_scalar = 1.0 / 5040; +const double c8_scalar = 1.0 / 40320; +const double c9_scalar = 1.0 / 362880; +const double c10_scalar = 1.0 / 3628800; +const double c11_scalar = 1.0 / 39916800; +const double c12_scalar = 1.0 / 479001600; +const double c13_scalar = 1.0 / 6227020800; diff --git a/headers/constants_float.hpp b/headers/constants_float.hpp index 4f42c62..c8c2126 100644 --- a/headers/constants_float.hpp +++ b/headers/constants_float.hpp @@ -104,16 +104,17 @@ const float cos_phi_sq = cos_phi * cos_phi; const size_t CACHE_BLOCK_SIZE = std::hardware_destructive_interference_size; -const double c0_scalar = 1.0 / 1; -const double c1_scalar = 1.0 / 1; -const double c2_scalar = 1.0 / 2; -const double c3_scalar = 1.0 / 6; -const double c4_scalar = 1.0 / 24; -const double c5_scalar = 1.0 / 120; -const double c6_scalar = 1.0 / 720; -const double c7_scalar = 1.0 / 5040; -const double c8_scalar = 1.0 / 40320; -const double c9_scalar = 1.0 / 362880; -const double c10_scalar = 1.0 / 3628800; -const double c11_scalar = 1.0 / 39916800; -const double c12_scalar = 1.0 / 479001600; +const float c0_scalar = 1.0 / 1; +const float c1_scalar = 1.0 / 1; +const float c2_scalar = 1.0 / 2; +const float c3_scalar = 1.0 / 6; +const float c4_scalar = 1.0 / 24; +const float c5_scalar = 1.0 / 120; +const float c6_scalar = 1.0 / 720; +const float c7_scalar = 1.0 / 5040; +const float c8_scalar = 1.0 / 40320; +const float c9_scalar = 1.0 / 362880; +const float c10_scalar = 1.0 / 3628800; +const float c11_scalar = 1.0 / 39916800; +const float c12_scalar = 1.0 / 479001600; +const float c13_scalar = 1.0 / 6227020800; diff --git a/measurements/memory/x86/1.log b/measurements/memory/x86/1.log index 76a392f..20be596 100644 --- a/measurements/memory/x86/1.log +++ b/measurements/memory/x86/1.log @@ -1,7 +1,7 @@ sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) Running the test with following options: -Number of threads: 1 +Number of threads: 8 Initializing random number generator from current time @@ -15,23 +15,23 @@ Initializing worker threads... Threads started! -Total operations: 20 ( 37.08 per second) +Total operations: 16 ( 94.31 per second) -20480.00 MiB transferred (37967.45 MiB/sec) +16384.00 MiB transferred (96577.44 MiB/sec) General statistics: - total time: 0.5378s - total number of events: 20 + total time: 0.1680s + total number of events: 16 Latency (ms): - min: 25.99 - avg: 26.87 - max: 33.18 - 95th percentile: 28.16 - sum: 537.47 + min: 73.61 + avg: 81.30 + max: 94.24 + 95th percentile: 90.78 + sum: 1300.79 Threads fairness: - events (avg/stddev): 20.0000/0.00 - execution time (avg/stddev): 0.5375/0.00 + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1626/0.00 diff --git a/measurements/memory/x86/10.log b/measurements/memory/x86/10.log new file mode 100644 index 0000000..e1355c5 --- /dev/null +++ b/measurements/memory/x86/10.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 79.70 per second) + +16384.00 MiB transferred (81607.97 MiB/sec) + + +General statistics: + total time: 0.1990s + total number of events: 16 + +Latency (ms): + min: 73.93 + avg: 95.91 + max: 115.12 + 95th percentile: 114.72 + sum: 1534.52 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1918/0.01 + diff --git a/measurements/memory/x86/100.log b/measurements/memory/x86/100.log new file mode 100644 index 0000000..af704aa --- /dev/null +++ b/measurements/memory/x86/100.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 66.20 per second) + +16384.00 MiB transferred (67785.69 MiB/sec) + + +General statistics: + total time: 0.2400s + total number of events: 16 + +Latency (ms): + min: 103.07 + avg: 118.76 + max: 133.11 + 95th percentile: 132.49 + sum: 1900.15 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2375/0.00 + diff --git a/measurements/memory/x86/11.log b/measurements/memory/x86/11.log new file mode 100644 index 0000000..64e6da9 --- /dev/null +++ b/measurements/memory/x86/11.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 65.88 per second) + +16384.00 MiB transferred (67456.51 MiB/sec) + + +General statistics: + total time: 0.2412s + total number of events: 16 + +Latency (ms): + min: 66.60 + avg: 106.05 + max: 174.46 + 95th percentile: 155.80 + sum: 1696.87 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2121/0.03 + diff --git a/measurements/memory/x86/12.log b/measurements/memory/x86/12.log new file mode 100644 index 0000000..f3e747a --- /dev/null +++ b/measurements/memory/x86/12.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 66.47 per second) + +16384.00 MiB transferred (68069.01 MiB/sec) + + +General statistics: + total time: 0.2390s + total number of events: 16 + +Latency (ms): + min: 53.56 + avg: 101.79 + max: 185.35 + 95th percentile: 158.63 + sum: 1628.59 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2036/0.03 + diff --git a/measurements/memory/x86/13.log b/measurements/memory/x86/13.log new file mode 100644 index 0000000..59104ff --- /dev/null +++ b/measurements/memory/x86/13.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 77.60 per second) + +16384.00 MiB transferred (79462.84 MiB/sec) + + +General statistics: + total time: 0.2045s + total number of events: 16 + +Latency (ms): + min: 43.46 + avg: 88.02 + max: 160.68 + 95th percentile: 153.02 + sum: 1408.36 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1760/0.02 + diff --git a/measurements/memory/x86/14.log b/measurements/memory/x86/14.log new file mode 100644 index 0000000..3263ba3 --- /dev/null +++ b/measurements/memory/x86/14.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 85.35 per second) + +16384.00 MiB transferred (87397.03 MiB/sec) + + +General statistics: + total time: 0.1858s + total number of events: 16 + +Latency (ms): + min: 62.81 + avg: 83.43 + max: 122.67 + 95th percentile: 123.28 + sum: 1334.89 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1669/0.01 + diff --git a/measurements/memory/x86/15.log b/measurements/memory/x86/15.log new file mode 100644 index 0000000..94633c9 --- /dev/null +++ b/measurements/memory/x86/15.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 79.07 per second) + +16384.00 MiB transferred (80971.56 MiB/sec) + + +General statistics: + total time: 0.2007s + total number of events: 16 + +Latency (ms): + min: 41.20 + avg: 85.98 + max: 159.24 + 95th percentile: 137.35 + sum: 1375.63 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1720/0.02 + diff --git a/measurements/memory/x86/16.log b/measurements/memory/x86/16.log new file mode 100644 index 0000000..6ba2d6c --- /dev/null +++ b/measurements/memory/x86/16.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 106.63 per second) + +16384.00 MiB transferred (109191.89 MiB/sec) + + +General statistics: + total time: 0.1484s + total number of events: 16 + +Latency (ms): + min: 68.17 + avg: 71.87 + max: 76.14 + 95th percentile: 75.82 + sum: 1149.93 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1437/0.00 + diff --git a/measurements/memory/x86/17.log b/measurements/memory/x86/17.log new file mode 100644 index 0000000..6444edd --- /dev/null +++ b/measurements/memory/x86/17.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 107.19 per second) + +16384.00 MiB transferred (109757.98 MiB/sec) + + +General statistics: + total time: 0.1476s + total number of events: 16 + +Latency (ms): + min: 71.89 + avg: 72.74 + max: 74.50 + 95th percentile: 74.46 + sum: 1163.80 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1455/0.00 + diff --git a/measurements/memory/x86/18.log b/measurements/memory/x86/18.log new file mode 100644 index 0000000..a9879dd --- /dev/null +++ b/measurements/memory/x86/18.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 73.09 per second) + +16384.00 MiB transferred (74844.08 MiB/sec) + + +General statistics: + total time: 0.2172s + total number of events: 16 + +Latency (ms): + min: 46.80 + avg: 93.61 + max: 170.30 + 95th percentile: 150.29 + sum: 1497.83 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1872/0.02 + diff --git a/measurements/memory/x86/19.log b/measurements/memory/x86/19.log new file mode 100644 index 0000000..7be3db9 --- /dev/null +++ b/measurements/memory/x86/19.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 99.55 per second) + +16384.00 MiB transferred (101941.22 MiB/sec) + + +General statistics: + total time: 0.1591s + total number of events: 16 + +Latency (ms): + min: 76.15 + avg: 77.89 + max: 82.07 + 95th percentile: 81.48 + sum: 1246.20 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1558/0.00 + diff --git a/measurements/memory/x86/2.log b/measurements/memory/x86/2.log index e582bbd..c480bd3 100644 --- a/measurements/memory/x86/2.log +++ b/measurements/memory/x86/2.log @@ -1,7 +1,7 @@ sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) Running the test with following options: -Number of threads: 1 +Number of threads: 8 Initializing random number generator from current time @@ -15,23 +15,23 @@ Initializing worker threads... Threads started! -Total operations: 20 ( 37.63 per second) +Total operations: 16 ( 80.42 per second) -20480.00 MiB transferred (38536.77 MiB/sec) +16384.00 MiB transferred (82353.79 MiB/sec) General statistics: - total time: 0.5299s - total number of events: 20 + total time: 0.1972s + total number of events: 16 Latency (ms): - min: 25.63 - avg: 26.48 - max: 36.38 - 95th percentile: 27.66 - sum: 529.61 + min: 71.20 + avg: 90.45 + max: 117.65 + 95th percentile: 116.80 + sum: 1447.14 Threads fairness: - events (avg/stddev): 20.0000/0.00 - execution time (avg/stddev): 0.5296/0.00 + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1809/0.01 diff --git a/measurements/memory/x86/20.log b/measurements/memory/x86/20.log new file mode 100644 index 0000000..847ed20 --- /dev/null +++ b/measurements/memory/x86/20.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 93.90 per second) + +16384.00 MiB transferred (96155.10 MiB/sec) + + +General statistics: + total time: 0.1687s + total number of events: 16 + +Latency (ms): + min: 71.25 + avg: 81.27 + max: 90.18 + 95th percentile: 89.16 + sum: 1300.34 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1625/0.00 + diff --git a/measurements/memory/x86/21.log b/measurements/memory/x86/21.log new file mode 100644 index 0000000..6005d9a --- /dev/null +++ b/measurements/memory/x86/21.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 113.14 per second) + +16384.00 MiB transferred (115856.56 MiB/sec) + + +General statistics: + total time: 0.1398s + total number of events: 16 + +Latency (ms): + min: 66.87 + avg: 69.44 + max: 72.73 + 95th percentile: 73.13 + sum: 1111.05 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1389/0.00 + diff --git a/measurements/memory/x86/22.log b/measurements/memory/x86/22.log new file mode 100644 index 0000000..f702ede --- /dev/null +++ b/measurements/memory/x86/22.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 74.21 per second) + +16384.00 MiB transferred (75991.45 MiB/sec) + + +General statistics: + total time: 0.2140s + total number of events: 16 + +Latency (ms): + min: 55.14 + avg: 91.61 + max: 158.54 + 95th percentile: 153.02 + sum: 1465.83 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1832/0.02 + diff --git a/measurements/memory/x86/23.log b/measurements/memory/x86/23.log new file mode 100644 index 0000000..a1f196c --- /dev/null +++ b/measurements/memory/x86/23.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 106.90 per second) + +16384.00 MiB transferred (109464.64 MiB/sec) + + +General statistics: + total time: 0.1481s + total number of events: 16 + +Latency (ms): + min: 66.13 + avg: 72.82 + max: 80.85 + 95th percentile: 80.03 + sum: 1165.16 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1456/0.00 + diff --git a/measurements/memory/x86/24.log b/measurements/memory/x86/24.log new file mode 100644 index 0000000..6dbab72 --- /dev/null +++ b/measurements/memory/x86/24.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 90.46 per second) + +16384.00 MiB transferred (92626.28 MiB/sec) + + +General statistics: + total time: 0.1752s + total number of events: 16 + +Latency (ms): + min: 38.71 + avg: 74.09 + max: 136.24 + 95th percentile: 130.13 + sum: 1185.49 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1482/0.02 + diff --git a/measurements/memory/x86/25.log b/measurements/memory/x86/25.log new file mode 100644 index 0000000..8889576 --- /dev/null +++ b/measurements/memory/x86/25.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 75.26 per second) + +16384.00 MiB transferred (77065.32 MiB/sec) + + +General statistics: + total time: 0.2109s + total number of events: 16 + +Latency (ms): + min: 75.17 + avg: 98.76 + max: 118.28 + 95th percentile: 116.80 + sum: 1580.09 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1975/0.01 + diff --git a/measurements/memory/x86/26.log b/measurements/memory/x86/26.log new file mode 100644 index 0000000..c62887e --- /dev/null +++ b/measurements/memory/x86/26.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 85.84 per second) + +16384.00 MiB transferred (87904.66 MiB/sec) + + +General statistics: + total time: 0.1846s + total number of events: 16 + +Latency (ms): + min: 46.68 + avg: 77.73 + max: 137.34 + 95th percentile: 134.90 + sum: 1243.61 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1555/0.02 + diff --git a/measurements/memory/x86/27.log b/measurements/memory/x86/27.log new file mode 100644 index 0000000..d34cdf7 --- /dev/null +++ b/measurements/memory/x86/27.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 68.61 per second) + +16384.00 MiB transferred (70260.31 MiB/sec) + + +General statistics: + total time: 0.2315s + total number of events: 16 + +Latency (ms): + min: 67.82 + avg: 106.58 + max: 163.55 + 95th percentile: 164.45 + sum: 1705.30 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2132/0.01 + diff --git a/measurements/memory/x86/28.log b/measurements/memory/x86/28.log new file mode 100644 index 0000000..0a06093 --- /dev/null +++ b/measurements/memory/x86/28.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 87.48 per second) + +16384.00 MiB transferred (89575.43 MiB/sec) + + +General statistics: + total time: 0.1813s + total number of events: 16 + +Latency (ms): + min: 69.25 + avg: 89.18 + max: 109.65 + 95th percentile: 108.68 + sum: 1426.91 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1784/0.00 + diff --git a/measurements/memory/x86/29.log b/measurements/memory/x86/29.log new file mode 100644 index 0000000..752f6e6 --- /dev/null +++ b/measurements/memory/x86/29.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 81.07 per second) + +16384.00 MiB transferred (83012.89 MiB/sec) + + +General statistics: + total time: 0.1957s + total number of events: 16 + +Latency (ms): + min: 77.98 + avg: 93.04 + max: 105.42 + 95th percentile: 102.97 + sum: 1488.64 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1861/0.01 + diff --git a/measurements/memory/x86/3.log b/measurements/memory/x86/3.log index 90efd3b..8538d68 100644 --- a/measurements/memory/x86/3.log +++ b/measurements/memory/x86/3.log @@ -1,7 +1,7 @@ sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) Running the test with following options: -Number of threads: 1 +Number of threads: 8 Initializing random number generator from current time @@ -15,23 +15,23 @@ Initializing worker threads... Threads started! -Total operations: 20 ( 37.35 per second) +Total operations: 16 ( 97.03 per second) -20480.00 MiB transferred (38249.60 MiB/sec) +16384.00 MiB transferred (99354.66 MiB/sec) General statistics: - total time: 0.5339s - total number of events: 20 + total time: 0.1632s + total number of events: 16 Latency (ms): - min: 26.01 - avg: 26.68 - max: 33.21 - 95th percentile: 27.66 - sum: 533.54 + min: 69.58 + avg: 78.02 + max: 85.93 + 95th percentile: 86.00 + sum: 1248.33 Threads fairness: - events (avg/stddev): 20.0000/0.00 - execution time (avg/stddev): 0.5335/0.00 + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1560/0.00 diff --git a/measurements/memory/x86/30.log b/measurements/memory/x86/30.log new file mode 100644 index 0000000..b2216b5 --- /dev/null +++ b/measurements/memory/x86/30.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 95.17 per second) + +16384.00 MiB transferred (97451.39 MiB/sec) + + +General statistics: + total time: 0.1665s + total number of events: 16 + +Latency (ms): + min: 69.09 + avg: 79.04 + max: 94.05 + 95th percentile: 94.10 + sum: 1264.67 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1581/0.01 + diff --git a/measurements/memory/x86/31.log b/measurements/memory/x86/31.log new file mode 100644 index 0000000..0b0687c --- /dev/null +++ b/measurements/memory/x86/31.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 72.12 per second) + +16384.00 MiB transferred (73852.41 MiB/sec) + + +General statistics: + total time: 0.2202s + total number of events: 16 + +Latency (ms): + min: 81.81 + avg: 107.56 + max: 132.03 + 95th percentile: 130.13 + sum: 1720.95 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2151/0.00 + diff --git a/measurements/memory/x86/32.log b/measurements/memory/x86/32.log new file mode 100644 index 0000000..1725676 --- /dev/null +++ b/measurements/memory/x86/32.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 100.76 per second) + +16384.00 MiB transferred (103176.04 MiB/sec) + + +General statistics: + total time: 0.1571s + total number of events: 16 + +Latency (ms): + min: 55.36 + avg: 71.95 + max: 101.65 + 95th percentile: 101.13 + sum: 1151.16 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1439/0.01 + diff --git a/measurements/memory/x86/33.log b/measurements/memory/x86/33.log new file mode 100644 index 0000000..306f47b --- /dev/null +++ b/measurements/memory/x86/33.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 74.95 per second) + +16384.00 MiB transferred (76752.90 MiB/sec) + + +General statistics: + total time: 0.2117s + total number of events: 16 + +Latency (ms): + min: 89.85 + avg: 103.90 + max: 116.44 + 95th percentile: 114.72 + sum: 1662.43 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2078/0.00 + diff --git a/measurements/memory/x86/34.log b/measurements/memory/x86/34.log new file mode 100644 index 0000000..7aa880b --- /dev/null +++ b/measurements/memory/x86/34.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 102.43 per second) + +16384.00 MiB transferred (104883.79 MiB/sec) + + +General statistics: + total time: 0.1546s + total number of events: 16 + +Latency (ms): + min: 73.74 + avg: 75.39 + max: 80.49 + 95th percentile: 77.19 + sum: 1206.24 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1508/0.00 + diff --git a/measurements/memory/x86/35.log b/measurements/memory/x86/35.log new file mode 100644 index 0000000..da62781 --- /dev/null +++ b/measurements/memory/x86/35.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 79.44 per second) + +16384.00 MiB transferred (81349.95 MiB/sec) + + +General statistics: + total time: 0.1996s + total number of events: 16 + +Latency (ms): + min: 53.35 + avg: 81.47 + max: 146.20 + 95th percentile: 132.49 + sum: 1303.50 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1629/0.02 + diff --git a/measurements/memory/x86/36.log b/measurements/memory/x86/36.log new file mode 100644 index 0000000..ec6a67f --- /dev/null +++ b/measurements/memory/x86/36.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 109.14 per second) + +16384.00 MiB transferred (111754.38 MiB/sec) + + +General statistics: + total time: 0.1450s + total number of events: 16 + +Latency (ms): + min: 64.93 + avg: 68.84 + max: 79.89 + 95th percentile: 70.55 + sum: 1101.39 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1377/0.00 + diff --git a/measurements/memory/x86/37.log b/measurements/memory/x86/37.log new file mode 100644 index 0000000..683dcc3 --- /dev/null +++ b/measurements/memory/x86/37.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 84.17 per second) + +16384.00 MiB transferred (86187.34 MiB/sec) + + +General statistics: + total time: 0.1878s + total number of events: 16 + +Latency (ms): + min: 75.26 + avg: 92.03 + max: 109.92 + 95th percentile: 108.68 + sum: 1472.49 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1841/0.00 + diff --git a/measurements/memory/x86/38.log b/measurements/memory/x86/38.log new file mode 100644 index 0000000..0555595 --- /dev/null +++ b/measurements/memory/x86/38.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 90.86 per second) + +16384.00 MiB transferred (93044.66 MiB/sec) + + +General statistics: + total time: 0.1744s + total number of events: 16 + +Latency (ms): + min: 67.71 + avg: 83.70 + max: 99.33 + 95th percentile: 97.55 + sum: 1339.14 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1674/0.00 + diff --git a/measurements/memory/x86/39.log b/measurements/memory/x86/39.log new file mode 100644 index 0000000..8e7e4c1 --- /dev/null +++ b/measurements/memory/x86/39.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 81.17 per second) + +16384.00 MiB transferred (83115.57 MiB/sec) + + +General statistics: + total time: 0.1951s + total number of events: 16 + +Latency (ms): + min: 86.50 + avg: 94.28 + max: 102.49 + 95th percentile: 101.13 + sum: 1508.50 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1886/0.00 + diff --git a/measurements/memory/x86/4.log b/measurements/memory/x86/4.log new file mode 100644 index 0000000..8af7906 --- /dev/null +++ b/measurements/memory/x86/4.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 92.61 per second) + +16384.00 MiB transferred (94828.99 MiB/sec) + + +General statistics: + total time: 0.1712s + total number of events: 16 + +Latency (ms): + min: 81.35 + avg: 83.98 + max: 88.16 + 95th percentile: 87.56 + sum: 1343.62 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1680/0.00 + diff --git a/measurements/memory/x86/40.log b/measurements/memory/x86/40.log new file mode 100644 index 0000000..62dc94a --- /dev/null +++ b/measurements/memory/x86/40.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 72.71 per second) + +16384.00 MiB transferred (74459.75 MiB/sec) + + +General statistics: + total time: 0.2184s + total number of events: 16 + +Latency (ms): + min: 50.76 + avg: 91.52 + max: 167.45 + 95th percentile: 106.75 + sum: 1464.29 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1830/0.02 + diff --git a/measurements/memory/x86/41.log b/measurements/memory/x86/41.log new file mode 100644 index 0000000..11893a8 --- /dev/null +++ b/measurements/memory/x86/41.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 60.86 per second) + +16384.00 MiB transferred (62318.33 MiB/sec) + + +General statistics: + total time: 0.2613s + total number of events: 16 + +Latency (ms): + min: 78.09 + avg: 119.23 + max: 183.07 + 95th percentile: 173.58 + sum: 1907.73 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2385/0.02 + diff --git a/measurements/memory/x86/42.log b/measurements/memory/x86/42.log new file mode 100644 index 0000000..8d88e57 --- /dev/null +++ b/measurements/memory/x86/42.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 56.03 per second) + +16384.00 MiB transferred (57372.39 MiB/sec) + + +General statistics: + total time: 0.2837s + total number of events: 16 + +Latency (ms): + min: 61.31 + avg: 125.06 + max: 215.37 + 95th percentile: 211.60 + sum: 2001.02 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2501/0.02 + diff --git a/measurements/memory/x86/43.log b/measurements/memory/x86/43.log new file mode 100644 index 0000000..1b510fe --- /dev/null +++ b/measurements/memory/x86/43.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 58.62 per second) + +16384.00 MiB transferred (60026.12 MiB/sec) + + +General statistics: + total time: 0.2713s + total number of events: 16 + +Latency (ms): + min: 63.69 + avg: 119.17 + max: 207.46 + 95th percentile: 183.21 + sum: 1906.77 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2383/0.02 + diff --git a/measurements/memory/x86/44.log b/measurements/memory/x86/44.log new file mode 100644 index 0000000..4314166 --- /dev/null +++ b/measurements/memory/x86/44.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 102.95 per second) + +16384.00 MiB transferred (105422.76 MiB/sec) + + +General statistics: + total time: 0.1538s + total number of events: 16 + +Latency (ms): + min: 69.90 + avg: 73.58 + max: 83.68 + 95th percentile: 77.19 + sum: 1177.29 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1472/0.00 + diff --git a/measurements/memory/x86/45.log b/measurements/memory/x86/45.log new file mode 100644 index 0000000..75293fa --- /dev/null +++ b/measurements/memory/x86/45.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 79.75 per second) + +16384.00 MiB transferred (81660.42 MiB/sec) + + +General statistics: + total time: 0.1990s + total number of events: 16 + +Latency (ms): + min: 71.18 + avg: 91.03 + max: 120.29 + 95th percentile: 116.80 + sum: 1456.43 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1821/0.01 + diff --git a/measurements/memory/x86/46.log b/measurements/memory/x86/46.log new file mode 100644 index 0000000..b56382c --- /dev/null +++ b/measurements/memory/x86/46.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 77.34 per second) + +16384.00 MiB transferred (79191.68 MiB/sec) + + +General statistics: + total time: 0.2052s + total number of events: 16 + +Latency (ms): + min: 86.09 + avg: 98.47 + max: 118.97 + 95th percentile: 118.92 + sum: 1575.56 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1969/0.01 + diff --git a/measurements/memory/x86/47.log b/measurements/memory/x86/47.log new file mode 100644 index 0000000..abc8e9b --- /dev/null +++ b/measurements/memory/x86/47.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 64.33 per second) + +16384.00 MiB transferred (65869.83 MiB/sec) + + +General statistics: + total time: 0.2471s + total number of events: 16 + +Latency (ms): + min: 84.56 + avg: 114.39 + max: 157.96 + 95th percentile: 132.49 + sum: 1830.24 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2288/0.01 + diff --git a/measurements/memory/x86/48.log b/measurements/memory/x86/48.log new file mode 100644 index 0000000..cc967c8 --- /dev/null +++ b/measurements/memory/x86/48.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 64.70 per second) + +16384.00 MiB transferred (66250.58 MiB/sec) + + +General statistics: + total time: 0.2457s + total number of events: 16 + +Latency (ms): + min: 91.94 + avg: 116.01 + max: 153.54 + 95th percentile: 147.61 + sum: 1856.11 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2320/0.01 + diff --git a/measurements/memory/x86/49.log b/measurements/memory/x86/49.log new file mode 100644 index 0000000..b7422e8 --- /dev/null +++ b/measurements/memory/x86/49.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 98.24 per second) + +16384.00 MiB transferred (100600.51 MiB/sec) + + +General statistics: + total time: 0.1612s + total number of events: 16 + +Latency (ms): + min: 62.93 + avg: 74.93 + max: 97.80 + 95th percentile: 97.55 + sum: 1198.94 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1499/0.01 + diff --git a/measurements/memory/x86/5.log b/measurements/memory/x86/5.log new file mode 100644 index 0000000..e1ca283 --- /dev/null +++ b/measurements/memory/x86/5.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 92.90 per second) + +16384.00 MiB transferred (95129.19 MiB/sec) + + +General statistics: + total time: 0.1706s + total number of events: 16 + +Latency (ms): + min: 77.25 + avg: 82.32 + max: 87.69 + 95th percentile: 87.56 + sum: 1317.17 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1646/0.00 + diff --git a/measurements/memory/x86/50.log b/measurements/memory/x86/50.log new file mode 100644 index 0000000..52ec9df --- /dev/null +++ b/measurements/memory/x86/50.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 73.53 per second) + +16384.00 MiB transferred (75296.15 MiB/sec) + + +General statistics: + total time: 0.2158s + total number of events: 16 + +Latency (ms): + min: 88.22 + avg: 106.84 + max: 125.58 + 95th percentile: 123.28 + sum: 1709.51 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2137/0.00 + diff --git a/measurements/memory/x86/51.log b/measurements/memory/x86/51.log new file mode 100644 index 0000000..a78d21c --- /dev/null +++ b/measurements/memory/x86/51.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 91.14 per second) + +16384.00 MiB transferred (93328.72 MiB/sec) + + +General statistics: + total time: 0.1739s + total number of events: 16 + +Latency (ms): + min: 71.66 + avg: 84.75 + max: 97.86 + 95th percentile: 97.55 + sum: 1356.00 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1695/0.00 + diff --git a/measurements/memory/x86/52.log b/measurements/memory/x86/52.log new file mode 100644 index 0000000..156bf31 --- /dev/null +++ b/measurements/memory/x86/52.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 97.96 per second) + +16384.00 MiB transferred (100309.26 MiB/sec) + + +General statistics: + total time: 0.1617s + total number of events: 16 + +Latency (ms): + min: 73.00 + avg: 75.99 + max: 87.22 + 95th percentile: 77.19 + sum: 1215.88 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1520/0.00 + diff --git a/measurements/memory/x86/53.log b/measurements/memory/x86/53.log new file mode 100644 index 0000000..5bec690 --- /dev/null +++ b/measurements/memory/x86/53.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 80.30 per second) + +16384.00 MiB transferred (82231.25 MiB/sec) + + +General statistics: + total time: 0.1976s + total number of events: 16 + +Latency (ms): + min: 72.09 + avg: 85.76 + max: 121.61 + 95th percentile: 108.68 + sum: 1372.23 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1715/0.02 + diff --git a/measurements/memory/x86/54.log b/measurements/memory/x86/54.log new file mode 100644 index 0000000..5392026 --- /dev/null +++ b/measurements/memory/x86/54.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 100.45 per second) + +16384.00 MiB transferred (102860.54 MiB/sec) + + +General statistics: + total time: 0.1576s + total number of events: 16 + +Latency (ms): + min: 67.37 + avg: 75.38 + max: 90.13 + 95th percentile: 84.47 + sum: 1206.09 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1508/0.00 + diff --git a/measurements/memory/x86/55.log b/measurements/memory/x86/55.log new file mode 100644 index 0000000..b080f0c --- /dev/null +++ b/measurements/memory/x86/55.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 100.98 per second) + +16384.00 MiB transferred (103399.91 MiB/sec) + + +General statistics: + total time: 0.1567s + total number of events: 16 + +Latency (ms): + min: 71.44 + avg: 76.15 + max: 80.74 + 95th percentile: 80.03 + sum: 1218.39 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1523/0.00 + diff --git a/measurements/memory/x86/56.log b/measurements/memory/x86/56.log new file mode 100644 index 0000000..6035a9a --- /dev/null +++ b/measurements/memory/x86/56.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 59.11 per second) + +16384.00 MiB transferred (60528.41 MiB/sec) + + +General statistics: + total time: 0.2691s + total number of events: 16 + +Latency (ms): + min: 109.87 + avg: 130.23 + max: 151.46 + 95th percentile: 137.35 + sum: 2083.66 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2605/0.01 + diff --git a/measurements/memory/x86/57.log b/measurements/memory/x86/57.log new file mode 100644 index 0000000..d9f9b48 --- /dev/null +++ b/measurements/memory/x86/57.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 82.52 per second) + +16384.00 MiB transferred (84499.80 MiB/sec) + + +General statistics: + total time: 0.1923s + total number of events: 16 + +Latency (ms): + min: 76.98 + avg: 91.58 + max: 107.30 + 95th percentile: 104.84 + sum: 1465.21 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1832/0.01 + diff --git a/measurements/memory/x86/58.log b/measurements/memory/x86/58.log new file mode 100644 index 0000000..e84083d --- /dev/null +++ b/measurements/memory/x86/58.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 107.72 per second) + +16384.00 MiB transferred (110301.47 MiB/sec) + + +General statistics: + total time: 0.1467s + total number of events: 16 + +Latency (ms): + min: 59.77 + avg: 69.22 + max: 86.69 + 95th percentile: 86.00 + sum: 1107.51 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1384/0.00 + diff --git a/measurements/memory/x86/59.log b/measurements/memory/x86/59.log new file mode 100644 index 0000000..2b135b8 --- /dev/null +++ b/measurements/memory/x86/59.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 79.12 per second) + +16384.00 MiB transferred (81016.71 MiB/sec) + + +General statistics: + total time: 0.2006s + total number of events: 16 + +Latency (ms): + min: 62.97 + avg: 88.24 + max: 137.28 + 95th percentile: 137.35 + sum: 1411.77 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1765/0.01 + diff --git a/measurements/memory/x86/6.log b/measurements/memory/x86/6.log new file mode 100644 index 0000000..87f180d --- /dev/null +++ b/measurements/memory/x86/6.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 103.49 per second) + +16384.00 MiB transferred (105978.10 MiB/sec) + + +General statistics: + total time: 0.1530s + total number of events: 16 + +Latency (ms): + min: 60.23 + avg: 72.64 + max: 92.48 + 95th percentile: 92.42 + sum: 1162.25 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1453/0.00 + diff --git a/measurements/memory/x86/60.log b/measurements/memory/x86/60.log new file mode 100644 index 0000000..59623d5 --- /dev/null +++ b/measurements/memory/x86/60.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 65.67 per second) + +16384.00 MiB transferred (67246.47 MiB/sec) + + +General statistics: + total time: 0.2420s + total number of events: 16 + +Latency (ms): + min: 67.54 + avg: 104.29 + max: 174.02 + 95th percentile: 161.51 + sum: 1668.57 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2086/0.03 + diff --git a/measurements/memory/x86/61.log b/measurements/memory/x86/61.log new file mode 100644 index 0000000..1d4bdb3 --- /dev/null +++ b/measurements/memory/x86/61.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 68.65 per second) + +16384.00 MiB transferred (70295.82 MiB/sec) + + +General statistics: + total time: 0.2315s + total number of events: 16 + +Latency (ms): + min: 50.78 + avg: 101.12 + max: 180.36 + 95th percentile: 167.44 + sum: 1617.89 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2022/0.02 + diff --git a/measurements/memory/x86/62.log b/measurements/memory/x86/62.log new file mode 100644 index 0000000..d46ac65 --- /dev/null +++ b/measurements/memory/x86/62.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 104.42 per second) + +16384.00 MiB transferred (106924.11 MiB/sec) + + +General statistics: + total time: 0.1516s + total number of events: 16 + +Latency (ms): + min: 72.20 + avg: 73.92 + max: 79.13 + 95th percentile: 75.82 + sum: 1182.73 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1478/0.00 + diff --git a/measurements/memory/x86/63.log b/measurements/memory/x86/63.log new file mode 100644 index 0000000..41d9828 --- /dev/null +++ b/measurements/memory/x86/63.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 77.75 per second) + +16384.00 MiB transferred (79616.87 MiB/sec) + + +General statistics: + total time: 0.2042s + total number of events: 16 + +Latency (ms): + min: 75.27 + avg: 94.69 + max: 112.35 + 95th percentile: 110.66 + sum: 1515.01 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1894/0.01 + diff --git a/measurements/memory/x86/64.log b/measurements/memory/x86/64.log new file mode 100644 index 0000000..57f1905 --- /dev/null +++ b/measurements/memory/x86/64.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 97.19 per second) + +16384.00 MiB transferred (99527.47 MiB/sec) + + +General statistics: + total time: 0.1630s + total number of events: 16 + +Latency (ms): + min: 76.50 + avg: 78.76 + max: 86.21 + 95th percentile: 80.03 + sum: 1260.24 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1575/0.00 + diff --git a/measurements/memory/x86/65.log b/measurements/memory/x86/65.log new file mode 100644 index 0000000..9398c23 --- /dev/null +++ b/measurements/memory/x86/65.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 103.22 per second) + +16384.00 MiB transferred (105698.74 MiB/sec) + + +General statistics: + total time: 0.1533s + total number of events: 16 + +Latency (ms): + min: 72.93 + avg: 75.41 + max: 80.29 + 95th percentile: 77.19 + sum: 1206.61 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1508/0.00 + diff --git a/measurements/memory/x86/66.log b/measurements/memory/x86/66.log new file mode 100644 index 0000000..191f5a7 --- /dev/null +++ b/measurements/memory/x86/66.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 107.62 per second) + +16384.00 MiB transferred (110198.57 MiB/sec) + + +General statistics: + total time: 0.1470s + total number of events: 16 + +Latency (ms): + min: 67.98 + avg: 71.21 + max: 78.78 + 95th percentile: 78.60 + sum: 1139.32 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1424/0.00 + diff --git a/measurements/memory/x86/67.log b/measurements/memory/x86/67.log new file mode 100644 index 0000000..812a343 --- /dev/null +++ b/measurements/memory/x86/67.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 101.07 per second) + +16384.00 MiB transferred (103493.97 MiB/sec) + + +General statistics: + total time: 0.1558s + total number of events: 16 + +Latency (ms): + min: 75.14 + avg: 76.93 + max: 79.56 + 95th percentile: 78.60 + sum: 1230.83 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1539/0.00 + diff --git a/measurements/memory/x86/68.log b/measurements/memory/x86/68.log new file mode 100644 index 0000000..b20da08 --- /dev/null +++ b/measurements/memory/x86/68.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 76.38 per second) + +16384.00 MiB transferred (78212.49 MiB/sec) + + +General statistics: + total time: 0.2078s + total number of events: 16 + +Latency (ms): + min: 71.66 + avg: 100.03 + max: 126.82 + 95th percentile: 125.52 + sum: 1600.41 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2001/0.00 + diff --git a/measurements/memory/x86/69.log b/measurements/memory/x86/69.log new file mode 100644 index 0000000..08755aa --- /dev/null +++ b/measurements/memory/x86/69.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 93.84 per second) + +16384.00 MiB transferred (96089.15 MiB/sec) + + +General statistics: + total time: 0.1689s + total number of events: 16 + +Latency (ms): + min: 56.05 + avg: 75.88 + max: 112.65 + 95th percentile: 110.66 + sum: 1214.13 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1518/0.01 + diff --git a/measurements/memory/x86/7.log b/measurements/memory/x86/7.log new file mode 100644 index 0000000..71a9eda --- /dev/null +++ b/measurements/memory/x86/7.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 80.69 per second) + +16384.00 MiB transferred (82629.39 MiB/sec) + + +General statistics: + total time: 0.1967s + total number of events: 16 + +Latency (ms): + min: 60.99 + avg: 83.05 + max: 135.57 + 95th percentile: 130.13 + sum: 1328.87 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1661/0.02 + diff --git a/measurements/memory/x86/70.log b/measurements/memory/x86/70.log new file mode 100644 index 0000000..362ca23 --- /dev/null +++ b/measurements/memory/x86/70.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 67.80 per second) + +16384.00 MiB transferred (69422.44 MiB/sec) + + +General statistics: + total time: 0.2343s + total number of events: 16 + +Latency (ms): + min: 98.37 + avg: 114.84 + max: 130.48 + 95th percentile: 130.13 + sum: 1837.43 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2297/0.00 + diff --git a/measurements/memory/x86/71.log b/measurements/memory/x86/71.log new file mode 100644 index 0000000..c611256 --- /dev/null +++ b/measurements/memory/x86/71.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 75.79 per second) + +16384.00 MiB transferred (77610.77 MiB/sec) + + +General statistics: + total time: 0.2095s + total number of events: 16 + +Latency (ms): + min: 39.52 + avg: 89.44 + max: 169.73 + 95th percentile: 142.39 + sum: 1431.06 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1789/0.02 + diff --git a/measurements/memory/x86/72.log b/measurements/memory/x86/72.log new file mode 100644 index 0000000..597887a --- /dev/null +++ b/measurements/memory/x86/72.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 92.77 per second) + +16384.00 MiB transferred (94996.97 MiB/sec) + + +General statistics: + total time: 0.1707s + total number of events: 16 + +Latency (ms): + min: 70.15 + avg: 79.20 + max: 95.24 + 95th percentile: 95.81 + sum: 1267.15 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1584/0.01 + diff --git a/measurements/memory/x86/73.log b/measurements/memory/x86/73.log new file mode 100644 index 0000000..cf96af7 --- /dev/null +++ b/measurements/memory/x86/73.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 116.60 per second) + +16384.00 MiB transferred (119396.61 MiB/sec) + + +General statistics: + total time: 0.1355s + total number of events: 16 + +Latency (ms): + min: 65.06 + avg: 66.95 + max: 70.12 + 95th percentile: 70.55 + sum: 1071.20 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1339/0.00 + diff --git a/measurements/memory/x86/74.log b/measurements/memory/x86/74.log new file mode 100644 index 0000000..0aebcff --- /dev/null +++ b/measurements/memory/x86/74.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 80.07 per second) + +16384.00 MiB transferred (81996.65 MiB/sec) + + +General statistics: + total time: 0.1982s + total number of events: 16 + +Latency (ms): + min: 80.41 + avg: 94.63 + max: 107.04 + 95th percentile: 106.75 + sum: 1514.10 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1893/0.00 + diff --git a/measurements/memory/x86/75.log b/measurements/memory/x86/75.log new file mode 100644 index 0000000..bee58ff --- /dev/null +++ b/measurements/memory/x86/75.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 63.34 per second) + +16384.00 MiB transferred (64858.00 MiB/sec) + + +General statistics: + total time: 0.2510s + total number of events: 16 + +Latency (ms): + min: 61.57 + avg: 111.55 + max: 189.27 + 95th percentile: 144.97 + sum: 1784.77 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2231/0.02 + diff --git a/measurements/memory/x86/76.log b/measurements/memory/x86/76.log new file mode 100644 index 0000000..bca2b65 --- /dev/null +++ b/measurements/memory/x86/76.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 103.91 per second) + +16384.00 MiB transferred (106405.03 MiB/sec) + + +General statistics: + total time: 0.1523s + total number of events: 16 + +Latency (ms): + min: 73.36 + avg: 74.61 + max: 77.00 + 95th percentile: 75.82 + sum: 1193.76 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1492/0.00 + diff --git a/measurements/memory/x86/77.log b/measurements/memory/x86/77.log new file mode 100644 index 0000000..536162e --- /dev/null +++ b/measurements/memory/x86/77.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 100.33 per second) + +16384.00 MiB transferred (102732.83 MiB/sec) + + +General statistics: + total time: 0.1578s + total number of events: 16 + +Latency (ms): + min: 73.33 + avg: 75.81 + max: 83.97 + 95th percentile: 80.03 + sum: 1212.89 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1516/0.00 + diff --git a/measurements/memory/x86/78.log b/measurements/memory/x86/78.log new file mode 100644 index 0000000..0736528 --- /dev/null +++ b/measurements/memory/x86/78.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 91.10 per second) + +16384.00 MiB transferred (93284.55 MiB/sec) + + +General statistics: + total time: 0.1739s + total number of events: 16 + +Latency (ms): + min: 67.50 + avg: 82.69 + max: 97.38 + 95th percentile: 95.81 + sum: 1323.05 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1654/0.00 + diff --git a/measurements/memory/x86/79.log b/measurements/memory/x86/79.log new file mode 100644 index 0000000..167349f --- /dev/null +++ b/measurements/memory/x86/79.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 58.18 per second) + +16384.00 MiB transferred (59578.81 MiB/sec) + + +General statistics: + total time: 0.2733s + total number of events: 16 + +Latency (ms): + min: 113.61 + avg: 132.06 + max: 159.52 + 95th percentile: 158.63 + sum: 2112.92 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2641/0.01 + diff --git a/measurements/memory/x86/8.log b/measurements/memory/x86/8.log new file mode 100644 index 0000000..22df35c --- /dev/null +++ b/measurements/memory/x86/8.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 77.95 per second) + +16384.00 MiB transferred (79822.28 MiB/sec) + + +General statistics: + total time: 0.2036s + total number of events: 16 + +Latency (ms): + min: 63.15 + avg: 95.63 + max: 119.12 + 95th percentile: 114.72 + sum: 1530.04 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1913/0.01 + diff --git a/measurements/memory/x86/80.log b/measurements/memory/x86/80.log new file mode 100644 index 0000000..fbceb76 --- /dev/null +++ b/measurements/memory/x86/80.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 68.49 per second) + +16384.00 MiB transferred (70135.44 MiB/sec) + + +General statistics: + total time: 0.2320s + total number of events: 16 + +Latency (ms): + min: 95.17 + avg: 112.71 + max: 127.46 + 95th percentile: 127.81 + sum: 1803.40 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2254/0.00 + diff --git a/measurements/memory/x86/81.log b/measurements/memory/x86/81.log new file mode 100644 index 0000000..bd6b5e6 --- /dev/null +++ b/measurements/memory/x86/81.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 116.86 per second) + +16384.00 MiB transferred (119668.49 MiB/sec) + + +General statistics: + total time: 0.1351s + total number of events: 16 + +Latency (ms): + min: 64.27 + avg: 66.49 + max: 70.74 + 95th percentile: 70.55 + sum: 1063.86 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1330/0.00 + diff --git a/measurements/memory/x86/82.log b/measurements/memory/x86/82.log new file mode 100644 index 0000000..8d918d6 --- /dev/null +++ b/measurements/memory/x86/82.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 95.62 per second) + +16384.00 MiB transferred (97915.95 MiB/sec) + + +General statistics: + total time: 0.1657s + total number of events: 16 + +Latency (ms): + min: 70.96 + avg: 78.06 + max: 94.60 + 95th percentile: 94.10 + sum: 1249.03 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1561/0.01 + diff --git a/measurements/memory/x86/83.log b/measurements/memory/x86/83.log new file mode 100644 index 0000000..799b987 --- /dev/null +++ b/measurements/memory/x86/83.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 69.73 per second) + +16384.00 MiB transferred (71398.50 MiB/sec) + + +General statistics: + total time: 0.2278s + total number of events: 16 + +Latency (ms): + min: 84.25 + avg: 111.48 + max: 136.03 + 95th percentile: 134.90 + sum: 1783.73 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2230/0.00 + diff --git a/measurements/memory/x86/84.log b/measurements/memory/x86/84.log new file mode 100644 index 0000000..9baaff8 --- /dev/null +++ b/measurements/memory/x86/84.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 101.15 per second) + +16384.00 MiB transferred (103577.94 MiB/sec) + + +General statistics: + total time: 0.1562s + total number of events: 16 + +Latency (ms): + min: 70.07 + avg: 75.75 + max: 80.38 + 95th percentile: 80.03 + sum: 1211.98 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1515/0.00 + diff --git a/measurements/memory/x86/85.log b/measurements/memory/x86/85.log new file mode 100644 index 0000000..f40ee83 --- /dev/null +++ b/measurements/memory/x86/85.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 65.93 per second) + +16384.00 MiB transferred (67511.91 MiB/sec) + + +General statistics: + total time: 0.2411s + total number of events: 16 + +Latency (ms): + min: 73.98 + avg: 109.55 + max: 159.84 + 95th percentile: 139.85 + sum: 1752.80 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2191/0.01 + diff --git a/measurements/memory/x86/86.log b/measurements/memory/x86/86.log new file mode 100644 index 0000000..e128580 --- /dev/null +++ b/measurements/memory/x86/86.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 81.84 per second) + +16384.00 MiB transferred (83802.42 MiB/sec) + + +General statistics: + total time: 0.1939s + total number of events: 16 + +Latency (ms): + min: 55.68 + avg: 86.71 + max: 137.93 + 95th percentile: 108.68 + sum: 1387.42 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1734/0.01 + diff --git a/measurements/memory/x86/87.log b/measurements/memory/x86/87.log new file mode 100644 index 0000000..13ceda5 --- /dev/null +++ b/measurements/memory/x86/87.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 98.85 per second) + +16384.00 MiB transferred (101222.95 MiB/sec) + + +General statistics: + total time: 0.1602s + total number of events: 16 + +Latency (ms): + min: 72.19 + avg: 77.10 + max: 87.91 + 95th percentile: 84.47 + sum: 1233.67 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1542/0.00 + diff --git a/measurements/memory/x86/88.log b/measurements/memory/x86/88.log new file mode 100644 index 0000000..fe73044 --- /dev/null +++ b/measurements/memory/x86/88.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 85.71 per second) + +16384.00 MiB transferred (87768.83 MiB/sec) + + +General statistics: + total time: 0.1849s + total number of events: 16 + +Latency (ms): + min: 75.80 + avg: 85.54 + max: 106.01 + 95th percentile: 99.33 + sum: 1368.70 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1711/0.01 + diff --git a/measurements/memory/x86/89.log b/measurements/memory/x86/89.log new file mode 100644 index 0000000..f1f34b6 --- /dev/null +++ b/measurements/memory/x86/89.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 98.25 per second) + +16384.00 MiB transferred (100612.47 MiB/sec) + + +General statistics: + total time: 0.1610s + total number of events: 16 + +Latency (ms): + min: 71.79 + avg: 76.11 + max: 88.03 + 95th percentile: 87.56 + sum: 1217.82 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1522/0.01 + diff --git a/measurements/memory/x86/9.log b/measurements/memory/x86/9.log new file mode 100644 index 0000000..e2858b5 --- /dev/null +++ b/measurements/memory/x86/9.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 75.63 per second) + +16384.00 MiB transferred (77441.55 MiB/sec) + + +General statistics: + total time: 0.2099s + total number of events: 16 + +Latency (ms): + min: 65.96 + avg: 88.37 + max: 143.80 + 95th percentile: 139.85 + sum: 1413.88 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1767/0.03 + diff --git a/measurements/memory/x86/90.log b/measurements/memory/x86/90.log new file mode 100644 index 0000000..266c126 --- /dev/null +++ b/measurements/memory/x86/90.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 81.70 per second) + +16384.00 MiB transferred (83664.49 MiB/sec) + + +General statistics: + total time: 0.1940s + total number of events: 16 + +Latency (ms): + min: 59.41 + avg: 78.25 + max: 134.42 + 95th percentile: 130.13 + sum: 1251.98 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1565/0.02 + diff --git a/measurements/memory/x86/91.log b/measurements/memory/x86/91.log new file mode 100644 index 0000000..83dd01b --- /dev/null +++ b/measurements/memory/x86/91.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 99.77 per second) + +16384.00 MiB transferred (102164.95 MiB/sec) + + +General statistics: + total time: 0.1588s + total number of events: 16 + +Latency (ms): + min: 72.55 + avg: 76.45 + max: 85.32 + 95th percentile: 80.03 + sum: 1223.26 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1529/0.00 + diff --git a/measurements/memory/x86/92.log b/measurements/memory/x86/92.log new file mode 100644 index 0000000..48eab6d --- /dev/null +++ b/measurements/memory/x86/92.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 82.26 per second) + +16384.00 MiB transferred (84232.58 MiB/sec) + + +General statistics: + total time: 0.1929s + total number of events: 16 + +Latency (ms): + min: 82.21 + avg: 94.02 + max: 102.11 + 95th percentile: 101.13 + sum: 1504.29 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1880/0.00 + diff --git a/measurements/memory/x86/93.log b/measurements/memory/x86/93.log new file mode 100644 index 0000000..24980a2 --- /dev/null +++ b/measurements/memory/x86/93.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 91.24 per second) + +16384.00 MiB transferred (93426.00 MiB/sec) + + +General statistics: + total time: 0.1737s + total number of events: 16 + +Latency (ms): + min: 47.90 + avg: 73.47 + max: 125.72 + 95th percentile: 121.08 + sum: 1175.48 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1469/0.02 + diff --git a/measurements/memory/x86/94.log b/measurements/memory/x86/94.log new file mode 100644 index 0000000..e2f0fed --- /dev/null +++ b/measurements/memory/x86/94.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 69.53 per second) + +16384.00 MiB transferred (71199.69 MiB/sec) + + +General statistics: + total time: 0.2285s + total number of events: 16 + +Latency (ms): + min: 63.70 + avg: 99.28 + max: 164.51 + 95th percentile: 155.80 + sum: 1588.48 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1986/0.02 + diff --git a/measurements/memory/x86/95.log b/measurements/memory/x86/95.log new file mode 100644 index 0000000..7fd015e --- /dev/null +++ b/measurements/memory/x86/95.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 104.42 per second) + +16384.00 MiB transferred (106925.10 MiB/sec) + + +General statistics: + total time: 0.1516s + total number of events: 16 + +Latency (ms): + min: 65.47 + avg: 70.92 + max: 86.03 + 95th percentile: 71.83 + sum: 1134.76 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1418/0.00 + diff --git a/measurements/memory/x86/96.log b/measurements/memory/x86/96.log new file mode 100644 index 0000000..892d81b --- /dev/null +++ b/measurements/memory/x86/96.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 71.77 per second) + +16384.00 MiB transferred (73490.57 MiB/sec) + + +General statistics: + total time: 0.2213s + total number of events: 16 + +Latency (ms): + min: 79.58 + avg: 105.45 + max: 125.14 + 95th percentile: 125.52 + sum: 1687.27 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2109/0.01 + diff --git a/measurements/memory/x86/97.log b/measurements/memory/x86/97.log new file mode 100644 index 0000000..f1163d6 --- /dev/null +++ b/measurements/memory/x86/97.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 90.32 per second) + +16384.00 MiB transferred (92483.77 MiB/sec) + + +General statistics: + total time: 0.1755s + total number of events: 16 + +Latency (ms): + min: 69.71 + avg: 82.12 + max: 97.22 + 95th percentile: 95.81 + sum: 1313.87 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1642/0.01 + diff --git a/measurements/memory/x86/98.log b/measurements/memory/x86/98.log new file mode 100644 index 0000000..f7cb680 --- /dev/null +++ b/measurements/memory/x86/98.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 74.54 per second) + +16384.00 MiB transferred (76330.40 MiB/sec) + + +General statistics: + total time: 0.2130s + total number of events: 16 + +Latency (ms): + min: 49.36 + avg: 90.31 + max: 163.46 + 95th percentile: 123.28 + sum: 1444.96 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.1806/0.02 + diff --git a/measurements/memory/x86/99.log b/measurements/memory/x86/99.log new file mode 100644 index 0000000..a7ce2c5 --- /dev/null +++ b/measurements/memory/x86/99.log @@ -0,0 +1,37 @@ +sysbench 1.0.20 (using system LuaJIT 2.1.1761786044) + +Running the test with following options: +Number of threads: 8 +Initializing random number generator from current time + + +Running memory speed test with the following options: + block size: 1048576KiB + total size: 20480MiB + operation: read + scope: global + +Initializing worker threads... + +Threads started! + +Total operations: 16 ( 68.00 per second) + +16384.00 MiB transferred (69636.56 MiB/sec) + + +General statistics: + total time: 0.2337s + total number of events: 16 + +Latency (ms): + min: 87.07 + avg: 111.85 + max: 131.42 + 95th percentile: 130.13 + sum: 1789.66 + +Threads fairness: + events (avg/stddev): 2.0000/0.00 + execution time (avg/stddev): 0.2237/0.01 + diff --git a/measurements/variant_baseline/x86/3.log b/measurements/variant_baseline/x86/3.log new file mode 100644 index 0000000..f3a1d6f --- /dev/null +++ b/measurements/variant_baseline/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_baseline.cpp -o main_baseline -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 27602905.00 cycles +P(n): 1.33 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 108346220.00 cycles +P(n): 1.34 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 436171900.00 cycles +P(n): 1.33 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 2815330460.00 cycles +P(n): 1.28 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 11366685120.00 cycles +P(n): 1.27 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 46485487760.00 cycles +P(n): 1.24 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 312273688920.00 cycles +P(n): 1.15 flops/cycle + diff --git a/measurements/variant_branchless/x86/2.log b/measurements/variant_branchless/x86/2.log new file mode 100644 index 0000000..8da19dc --- /dev/null +++ b/measurements/variant_branchless/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_branchless.cpp -o main_branchless -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 32618855.00 cycles +P(n): 1.13 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 129903020.00 cycles +P(n): 1.12 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 546607480.00 cycles +P(n): 1.06 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 3564103380.00 cycles +P(n): 1.01 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 14460744480.00 cycles +P(n): 1.00 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 59317253600.00 cycles +P(n): 0.97 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 386083944780.00 cycles +P(n): 0.93 flops/cycle + diff --git a/measurements/variant_branchless/x86/3.log b/measurements/variant_branchless/x86/3.log new file mode 100644 index 0000000..6d6f654 --- /dev/null +++ b/measurements/variant_branchless/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_branchless.cpp -o main_branchless -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 32549760.00 cycles +P(n): 1.13 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 132472520.00 cycles +P(n): 1.10 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 546899100.00 cycles +P(n): 1.06 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 3595898300.00 cycles +P(n): 1.00 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 14398657780.00 cycles +P(n): 1.00 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 59074417020.00 cycles +P(n): 0.98 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 384714694000.00 cycles +P(n): 0.94 flops/cycle + diff --git a/measurements/variant_branchless_sqrtfree/x86/2.log b/measurements/variant_branchless_sqrtfree/x86/2.log new file mode 100644 index 0000000..7072d5b --- /dev/null +++ b/measurements/variant_branchless_sqrtfree/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_branchless_sqrtfree.cpp -o main_branchless_sqrtfree -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 32048610.00 cycles +P(n): 1.15 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 124926140.00 cycles +P(n): 1.16 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 496226700.00 cycles +P(n): 1.17 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 3098696200.00 cycles +P(n): 1.16 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 12321978700.00 cycles +P(n): 1.17 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 49235152160.00 cycles +P(n): 1.17 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 307537206280.00 cycles +P(n): 1.17 flops/cycle + diff --git a/measurements/variant_branchless_sqrtfree/x86/3.log b/measurements/variant_branchless_sqrtfree/x86/3.log new file mode 100644 index 0000000..91b16f6 --- /dev/null +++ b/measurements/variant_branchless_sqrtfree/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_branchless_sqrtfree.cpp -o main_branchless_sqrtfree -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 31528725.00 cycles +P(n): 1.17 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 124375380.00 cycles +P(n): 1.17 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 494656240.00 cycles +P(n): 1.17 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 3069950280.00 cycles +P(n): 1.18 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 12264064020.00 cycles +P(n): 1.18 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 49136256080.00 cycles +P(n): 1.17 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 310316526840.00 cycles +P(n): 1.16 flops/cycle + diff --git a/measurements/variant_cutoff/x86/2.log b/measurements/variant_cutoff/x86/2.log new file mode 100644 index 0000000..e4aef82 --- /dev/null +++ b/measurements/variant_cutoff/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_cutoff.cpp -o main_cutoff -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 17857572.50 cycles +P(n): 2.06 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 76450530.00 cycles +P(n): 1.90 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 270167300.00 cycles +P(n): 2.14 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 1898509880.00 cycles +P(n): 1.90 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 7707918240.00 cycles +P(n): 1.87 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 31905756600.00 cycles +P(n): 1.81 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 215725945760.00 cycles +P(n): 1.67 flops/cycle + diff --git a/measurements/variant_cutoff/x86/3.log b/measurements/variant_cutoff/x86/3.log new file mode 100644 index 0000000..887fa38 --- /dev/null +++ b/measurements/variant_cutoff/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_cutoff.cpp -o main_cutoff -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 17637622.50 cycles +P(n): 2.08 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 76060470.00 cycles +P(n): 1.91 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 267233860.00 cycles +P(n): 2.17 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 1897077760.00 cycles +P(n): 1.90 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 7759546840.00 cycles +P(n): 1.86 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 32218084860.00 cycles +P(n): 1.79 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 216623652880.00 cycles +P(n): 1.66 flops/cycle + diff --git a/measurements/variant_cutoff_callsite/x86/2.log b/measurements/variant_cutoff_callsite/x86/2.log new file mode 100644 index 0000000..29a7e24 --- /dev/null +++ b/measurements/variant_cutoff_callsite/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_cutoff_callsite.cpp -o main_cutoff_callsite -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 16934235.00 cycles +P(n): 2.17 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 71336000.00 cycles +P(n): 2.04 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 260955100.00 cycles +P(n): 2.22 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 1819642180.00 cycles +P(n): 1.98 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 7536435560.00 cycles +P(n): 1.91 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 30984442660.00 cycles +P(n): 1.86 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 210935037300.00 cycles +P(n): 1.71 flops/cycle + diff --git a/measurements/variant_cutoff_callsite/x86/3.log b/measurements/variant_cutoff_callsite/x86/3.log new file mode 100644 index 0000000..62f62de --- /dev/null +++ b/measurements/variant_cutoff_callsite/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_cutoff_callsite.cpp -o main_cutoff_callsite -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 16651247.50 cycles +P(n): 2.21 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 71732010.00 cycles +P(n): 2.03 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 251676200.00 cycles +P(n): 2.30 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 1824751540.00 cycles +P(n): 1.98 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 7534812080.00 cycles +P(n): 1.91 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 31129863960.00 cycles +P(n): 1.85 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 210111990180.00 cycles +P(n): 1.71 flops/cycle + diff --git a/measurements/variant_float_baseline/x86/2.log b/measurements/variant_float_baseline/x86/2.log new file mode 100644 index 0000000..15682ec --- /dev/null +++ b/measurements/variant_float_baseline/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_baseline.cpp -o main_float_baseline -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 23906564.00 cycles +P(n): 1.54 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 94126864.00 cycles +P(n): 1.55 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 379665728.00 cycles +P(n): 1.52 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 2738376960.00 cycles +P(n): 1.32 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 11763845120.00 cycles +P(n): 1.23 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 51998625792.00 cycles +P(n): 1.11 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 369826004992.00 cycles +P(n): 0.97 flops/cycle + diff --git a/measurements/variant_float_baseline/x86/3.log b/measurements/variant_float_baseline/x86/3.log new file mode 100644 index 0000000..70e84bf --- /dev/null +++ b/measurements/variant_float_baseline/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_baseline.cpp -o main_float_baseline -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 23530572.00 cycles +P(n): 1.56 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 93875008.00 cycles +P(n): 1.55 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 380102016.00 cycles +P(n): 1.52 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 2731053824.00 cycles +P(n): 1.32 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 11666406400.00 cycles +P(n): 1.24 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 51928870912.00 cycles +P(n): 1.11 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 370410651648.00 cycles +P(n): 0.97 flops/cycle + diff --git a/measurements/variant_float_inlining/x86/2.log b/measurements/variant_float_inlining/x86/2.log new file mode 100644 index 0000000..054a921 --- /dev/null +++ b/measurements/variant_float_inlining/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining.cpp -o main_float_inlining -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 20872928.00 cycles +P(n): 1.76 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 83152760.00 cycles +P(n): 1.75 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 334965856.00 cycles +P(n): 1.73 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 2470004736.00 cycles +P(n): 1.46 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 10627587072.00 cycles +P(n): 1.36 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 47728148480.00 cycles +P(n): 1.21 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 342776479744.00 cycles +P(n): 1.05 flops/cycle + diff --git a/measurements/variant_float_inlining/x86/3.log b/measurements/variant_float_inlining/x86/3.log new file mode 100644 index 0000000..d041d11 --- /dev/null +++ b/measurements/variant_float_inlining/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining.cpp -o main_float_inlining -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 21161456.00 cycles +P(n): 1.74 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 84570152.00 cycles +P(n): 1.72 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 342739392.00 cycles +P(n): 1.69 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 2469612800.00 cycles +P(n): 1.46 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 10730601472.00 cycles +P(n): 1.34 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 47785230336.00 cycles +P(n): 1.21 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 342750101504.00 cycles +P(n): 1.05 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA/x86/2.log b/measurements/variant_float_inlining_SoA/x86/2.log new file mode 100644 index 0000000..8299833 --- /dev/null +++ b/measurements/variant_float_inlining_SoA/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA.cpp -o main_float_inlining_SoA -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 20983524.00 cycles +P(n): 1.75 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 85081848.00 cycles +P(n): 1.71 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 337773472.00 cycles +P(n): 1.71 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 2496699136.00 cycles +P(n): 1.44 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 10822607872.00 cycles +P(n): 1.33 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 48131854336.00 cycles +P(n): 1.20 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 346968686592.00 cycles +P(n): 1.04 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA/x86/3.log b/measurements/variant_float_inlining_SoA/x86/3.log new file mode 100644 index 0000000..92e5084 --- /dev/null +++ b/measurements/variant_float_inlining_SoA/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA.cpp -o main_float_inlining_SoA -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 21201458.00 cycles +P(n): 1.73 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 84348232.00 cycles +P(n): 1.72 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 338714912.00 cycles +P(n): 1.71 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 2491379712.00 cycles +P(n): 1.45 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 10827898880.00 cycles +P(n): 1.33 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 48295981056.00 cycles +P(n): 1.19 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 346709753856.00 cycles +P(n): 1.04 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/1.log new file mode 100644 index 0000000..6062c1a --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX2_polyexp_expfix.cpp -o main_float_inlining_SoA_AVX2_polyexp_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 5860437.00 cycles +P(n): 6.27 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 19736818.00 cycles +P(n): 7.37 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 71295200.00 cycles +P(n): 8.12 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 434200736.00 cycles +P(n): 8.31 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1690932352.00 cycles +P(n): 8.52 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 6726832128.00 cycles +P(n): 8.57 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 41595662336.00 cycles +P(n): 8.66 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 166348996608.00 cycles +P(n): 3.49 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/2.log new file mode 100644 index 0000000..652e0a6 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX2_polyexp_expfix.cpp -o main_float_inlining_SoA_AVX2_polyexp_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 5885449.00 cycles +P(n): 6.24 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 19775262.00 cycles +P(n): 7.36 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 71759640.00 cycles +P(n): 8.07 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 442073856.00 cycles +P(n): 8.16 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1698162944.00 cycles +P(n): 8.49 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 6719285248.00 cycles +P(n): 8.58 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 41795964928.00 cycles +P(n): 8.62 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 166340608000.00 cycles +P(n): 3.49 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/3.log new file mode 100644 index 0000000..543ba85 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX2_polyexp_expfix/x86/3.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 5839795.00 cycles +P(n): 6.29 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 19706848.00 cycles +P(n): 7.38 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 71913632.00 cycles +P(n): 8.05 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 431199296.00 cycles +P(n): 8.37 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1710698496.00 cycles +P(n): 8.43 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 6773665792.00 cycles +P(n): 8.51 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 43346759680.00 cycles +P(n): 8.31 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 169504800768.00 cycles +P(n): 3.43 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/1.log new file mode 100644 index 0000000..7e95d51 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix.cpp -o main_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 5075402.00 cycles +P(n): 7.24 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 16874942.00 cycles +P(n): 8.62 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 60586048.00 cycles +P(n): 9.56 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 363991840.00 cycles +P(n): 9.91 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1424352768.00 cycles +P(n): 10.12 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 5638619648.00 cycles +P(n): 10.22 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 35081228288.00 cycles +P(n): 10.26 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 140734889984.00 cycles +P(n): 4.13 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/2.log new file mode 100644 index 0000000..322109b --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/2.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 5095124.00 cycles +P(n): 7.21 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 16958378.00 cycles +P(n): 8.58 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 60894740.00 cycles +P(n): 9.51 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 364922464.00 cycles +P(n): 9.89 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1432131456.00 cycles +P(n): 10.07 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 5669585408.00 cycles +P(n): 10.16 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 35706060800.00 cycles +P(n): 10.08 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 143150546944.00 cycles +P(n): 4.06 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/3.log new file mode 100644 index 0000000..a1c9040 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix/x86/3.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 5107488.00 cycles +P(n): 7.19 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 16972588.00 cycles +P(n): 8.57 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 61120552.00 cycles +P(n): 9.47 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 375650720.00 cycles +P(n): 9.60 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1444334464.00 cycles +P(n): 9.98 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 5717088768.00 cycles +P(n): 10.08 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 36025249792.00 cycles +P(n): 10.00 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 143378251776.00 cycles +P(n): 4.05 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/1.log new file mode 100644 index 0000000..eab143b --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix.cpp -o main_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4870774.50 cycles +P(n): 7.54 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 15640118.00 cycles +P(n): 9.30 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 55310808.00 cycles +P(n): 10.47 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 329563872.00 cycles +P(n): 10.95 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1283268352.00 cycles +P(n): 11.23 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 5083250688.00 cycles +P(n): 11.34 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 31586570240.00 cycles +P(n): 11.40 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 126882955264.00 cycles +P(n): 4.58 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/2.log new file mode 100644 index 0000000..e4dcd7a --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/2.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4872185.50 cycles +P(n): 7.54 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 15664138.00 cycles +P(n): 9.29 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 55368740.00 cycles +P(n): 10.46 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 329987008.00 cycles +P(n): 10.93 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1293044736.00 cycles +P(n): 11.15 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 5130688512.00 cycles +P(n): 11.23 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 32060348416.00 cycles +P(n): 11.23 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 129057972224.00 cycles +P(n): 4.50 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/3.log new file mode 100644 index 0000000..da0c24a --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix/x86/3.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4901788.00 cycles +P(n): 7.50 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 15669965.00 cycles +P(n): 9.28 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 55911480.00 cycles +P(n): 10.35 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 338225088.00 cycles +P(n): 10.67 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1302161408.00 cycles +P(n): 11.07 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 5189515776.00 cycles +P(n): 11.11 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 32577761280.00 cycles +P(n): 11.05 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 129035010048.00 cycles +P(n): 4.50 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/1.log new file mode 100644 index 0000000..533d3a6 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4618692.00 cycles +P(n): 7.95 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14020708.00 cycles +P(n): 10.38 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 47426524.00 cycles +P(n): 12.21 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 271672832.00 cycles +P(n): 13.28 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1041892096.00 cycles +P(n): 13.84 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 4086357760.00 cycles +P(n): 14.10 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 25345890304.00 cycles +P(n): 14.21 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 100797374464.00 cycles +P(n): 5.77 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/2.log new file mode 100644 index 0000000..1d0ae94 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4660804.50 cycles +P(n): 7.88 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14015782.00 cycles +P(n): 10.38 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 47630040.00 cycles +P(n): 12.16 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 272007200.00 cycles +P(n): 13.26 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1042778816.00 cycles +P(n): 13.82 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 4092400640.00 cycles +P(n): 14.08 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 25352386560.00 cycles +P(n): 14.20 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 101285814272.00 cycles +P(n): 5.74 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/3.log new file mode 100644 index 0000000..49a7e56 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4633135.50 cycles +P(n): 7.93 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14098810.00 cycles +P(n): 10.32 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 47519168.00 cycles +P(n): 12.18 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 272423904.00 cycles +P(n): 13.24 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1060791424.00 cycles +P(n): 13.59 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 4102831872.00 cycles +P(n): 14.05 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 25357774848.00 cycles +P(n): 14.20 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 100551254016.00 cycles +P(n): 5.78 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/1.log new file mode 100644 index 0000000..7cc9274 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4899351.00 cycles +P(n): 7.50 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14704840.00 cycles +P(n): 9.89 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 48870456.00 cycles +P(n): 11.85 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 274548320.00 cycles +P(n): 13.14 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1067638016.00 cycles +P(n): 13.50 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 4133780736.00 cycles +P(n): 13.94 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 25536294912.00 cycles +P(n): 14.10 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 101531860992.00 cycles +P(n): 5.72 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/2.log new file mode 100644 index 0000000..b038931 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4906050.00 cycles +P(n): 7.49 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14798538.00 cycles +P(n): 9.83 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 48817384.00 cycles +P(n): 11.86 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 276943584.00 cycles +P(n): 13.03 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1052295168.00 cycles +P(n): 13.70 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 4133724672.00 cycles +P(n): 13.94 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 25570220032.00 cycles +P(n): 14.08 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 101490999296.00 cycles +P(n): 5.73 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/3.log new file mode 100644 index 0000000..ed48881 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4896082.00 cycles +P(n): 7.50 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14589518.00 cycles +P(n): 9.97 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 48579536.00 cycles +P(n): 11.92 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 275277376.00 cycles +P(n): 13.10 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1050094400.00 cycles +P(n): 13.73 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 4110344448.00 cycles +P(n): 14.02 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 25639516160.00 cycles +P(n): 14.04 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 101213003776.00 cycles +P(n): 5.74 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/1.log new file mode 100644 index 0000000..29aad47 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4444855.00 cycles +P(n): 8.27 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 13834708.00 cycles +P(n): 10.52 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 47410956.00 cycles +P(n): 12.21 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 276381408.00 cycles +P(n): 13.05 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1067362496.00 cycles +P(n): 13.51 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 4156325376.00 cycles +P(n): 13.87 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 26170245120.00 cycles +P(n): 13.76 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 104163885056.00 cycles +P(n): 5.58 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/2.log new file mode 100644 index 0000000..dcd470c --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4415419.00 cycles +P(n): 8.32 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 13731945.00 cycles +P(n): 10.59 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 47216112.00 cycles +P(n): 12.26 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 273902208.00 cycles +P(n): 13.17 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1066031616.00 cycles +P(n): 13.52 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 4168480512.00 cycles +P(n): 13.83 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 25959776256.00 cycles +P(n): 13.87 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 103256596480.00 cycles +P(n): 5.63 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/3.log new file mode 100644 index 0000000..a66e481 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4421310.50 cycles +P(n): 8.31 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 13851305.00 cycles +P(n): 10.50 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 47453300.00 cycles +P(n): 12.20 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 275350432.00 cycles +P(n): 13.10 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 1059425216.00 cycles +P(n): 13.61 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 4161480448.00 cycles +P(n): 13.85 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 25909958656.00 cycles +P(n): 13.90 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 102891044864.00 cycles +P(n): 5.65 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/1.log new file mode 100644 index 0000000..8b8601d --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4116743.00 cycles +P(n): 8.92 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14193060.00 cycles +P(n): 10.25 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 46275016.00 cycles +P(n): 12.51 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 250446432.00 cycles +P(n): 14.40 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 977844992.00 cycles +P(n): 14.74 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3811610624.00 cycles +P(n): 15.12 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 23616888832.00 cycles +P(n): 15.25 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 94000291840.00 cycles +P(n): 6.18 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/2.log new file mode 100644 index 0000000..2a209b9 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4130377.00 cycles +P(n): 8.90 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14179700.00 cycles +P(n): 10.26 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 46318220.00 cycles +P(n): 12.50 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 250998336.00 cycles +P(n): 14.37 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 982180672.00 cycles +P(n): 14.68 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3805426944.00 cycles +P(n): 15.14 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 23592302592.00 cycles +P(n): 15.26 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 93937680384.00 cycles +P(n): 6.19 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/3.log new file mode 100644 index 0000000..7f8cb13 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4107580.00 cycles +P(n): 8.94 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14142018.00 cycles +P(n): 10.29 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 46132236.00 cycles +P(n): 12.55 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 248790048.00 cycles +P(n): 14.50 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 974417088.00 cycles +P(n): 14.79 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3791391744.00 cycles +P(n): 15.20 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 23488210944.00 cycles +P(n): 15.33 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 93195214848.00 cycles +P(n): 6.24 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/1.log new file mode 100644 index 0000000..3ea961d --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4119329.50 cycles +P(n): 8.92 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14140615.00 cycles +P(n): 10.29 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 46104904.00 cycles +P(n): 12.56 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 248777184.00 cycles +P(n): 14.50 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 972575296.00 cycles +P(n): 14.82 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3793779712.00 cycles +P(n): 15.19 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 23662673920.00 cycles +P(n): 15.22 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 93648879616.00 cycles +P(n): 6.21 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/2.log new file mode 100644 index 0000000..29375a1 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4131873.00 cycles +P(n): 8.89 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14207365.00 cycles +P(n): 10.24 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 46157304.00 cycles +P(n): 12.54 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 249512304.00 cycles +P(n): 14.46 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 974145152.00 cycles +P(n): 14.80 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3796545280.00 cycles +P(n): 15.18 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 23539767296.00 cycles +P(n): 15.30 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 93385080832.00 cycles +P(n): 6.22 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/3.log new file mode 100644 index 0000000..d853e35 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4133901.25 cycles +P(n): 8.89 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14286805.00 cycles +P(n): 10.18 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 46514768.00 cycles +P(n): 12.45 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 250415104.00 cycles +P(n): 14.41 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 979476864.00 cycles +P(n): 14.72 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3790536448.00 cycles +P(n): 15.20 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 23435288576.00 cycles +P(n): 15.36 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 93591674880.00 cycles +P(n): 6.21 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/1.log new file mode 100644 index 0000000..4022b05 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4119765.00 cycles +P(n): 8.92 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14158772.00 cycles +P(n): 10.27 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 46276376.00 cycles +P(n): 12.51 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 249878624.00 cycles +P(n): 14.44 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 982863872.00 cycles +P(n): 14.67 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3826156544.00 cycles +P(n): 15.06 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 23693496320.00 cycles +P(n): 15.20 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 94222524416.00 cycles +P(n): 6.17 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/2.log new file mode 100644 index 0000000..4c1d8cf --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4102695.50 cycles +P(n): 8.96 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14151872.00 cycles +P(n): 10.28 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 46248272.00 cycles +P(n): 12.52 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 249935680.00 cycles +P(n): 14.43 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 977354240.00 cycles +P(n): 14.75 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3821584896.00 cycles +P(n): 15.08 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 23594674176.00 cycles +P(n): 15.26 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 94093844480.00 cycles +P(n): 6.18 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/3.log new file mode 100644 index 0000000..a80e32c --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 4124268.00 cycles +P(n): 8.91 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 14218675.00 cycles +P(n): 10.23 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 46843476.00 cycles +P(n): 12.36 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 250210640.00 cycles +P(n): 14.42 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 982352128.00 cycles +P(n): 14.67 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3823222016.00 cycles +P(n): 15.07 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 23695175680.00 cycles +P(n): 15.20 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 94304829440.00 cycles +P(n): 6.16 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/1.log new file mode 100644 index 0000000..fd8f66f --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 3472917.50 cycles +P(n): 10.58 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 11763622.00 cycles +P(n): 12.37 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 38070640.00 cycles +P(n): 15.21 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 204154320.00 cycles +P(n): 17.67 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 798999808.00 cycles +P(n): 18.04 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3114275584.00 cycles +P(n): 18.50 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 19146825728.00 cycles +P(n): 18.81 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 76207964160.00 cycles +P(n): 7.63 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/2.log new file mode 100644 index 0000000..0a1f7d4 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 3503500.00 cycles +P(n): 10.49 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 11802675.00 cycles +P(n): 12.33 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 37947776.00 cycles +P(n): 15.26 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 203323776.00 cycles +P(n): 17.74 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 821986944.00 cycles +P(n): 17.54 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3103710720.00 cycles +P(n): 18.57 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 19254915072.00 cycles +P(n): 18.70 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 76036898816.00 cycles +P(n): 7.64 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/3.log new file mode 100644 index 0000000..8fb271d --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 3474629.50 cycles +P(n): 10.57 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 11869545.00 cycles +P(n): 12.26 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 38112416.00 cycles +P(n): 15.19 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 203449264.00 cycles +P(n): 17.73 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 816738752.00 cycles +P(n): 17.65 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3081998592.00 cycles +P(n): 18.70 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 19241965568.00 cycles +P(n): 18.71 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 76032835584.00 cycles +P(n): 7.64 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/1.log new file mode 100644 index 0000000..ed597a5 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 3443131.25 cycles +P(n): 10.67 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 11289992.00 cycles +P(n): 12.89 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 36293512.00 cycles +P(n): 15.95 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 193259072.00 cycles +P(n): 18.67 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 752713344.00 cycles +P(n): 19.15 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 2940765440.00 cycles +P(n): 19.60 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 18122862592.00 cycles +P(n): 19.87 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 71869390848.00 cycles +P(n): 8.09 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/2.log new file mode 100644 index 0000000..08bfc3e --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/2.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 3387230.00 cycles +P(n): 10.85 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 11326786.00 cycles +P(n): 12.84 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 36351516.00 cycles +P(n): 15.93 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 194490336.00 cycles +P(n): 18.55 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 753201792.00 cycles +P(n): 19.14 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 2954236416.00 cycles +P(n): 19.51 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 18356828160.00 cycles +P(n): 19.62 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 73678970880.00 cycles +P(n): 7.89 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/3.log new file mode 100644 index 0000000..70f3e89 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved/x86/3.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 3445767.00 cycles +P(n): 10.66 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 11501729.00 cycles +P(n): 12.65 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 36756200.00 cycles +P(n): 15.75 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 198376320.00 cycles +P(n): 18.18 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 765950336.00 cycles +P(n): 18.82 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 2987576576.00 cycles +P(n): 19.29 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 18625347584.00 cycles +P(n): 19.33 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 73340780544.00 cycles +P(n): 7.92 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/1.log new file mode 100644 index 0000000..5b20e8e --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 2430659.75 cycles +P(n): 15.12 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 8285106.00 cycles +P(n): 17.56 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 30615050.00 cycles +P(n): 18.91 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 186199040.00 cycles +P(n): 19.37 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 728076288.00 cycles +P(n): 19.80 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 2895743232.00 cycles +P(n): 19.90 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 18180956160.00 cycles +P(n): 19.81 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 72372396032.00 cycles +P(n): 8.03 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/2.log new file mode 100644 index 0000000..66eac2b --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/2.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 2443465.25 cycles +P(n): 15.04 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 8370210.00 cycles +P(n): 17.38 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 30839560.00 cycles +P(n): 18.77 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 185338336.00 cycles +P(n): 19.46 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 737704256.00 cycles +P(n): 19.54 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 2915981056.00 cycles +P(n): 19.76 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 18362775552.00 cycles +P(n): 19.61 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 73707225088.00 cycles +P(n): 7.88 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/3.log new file mode 100644 index 0000000..a9c7550 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp/x86/3.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 2445340.00 cycles +P(n): 15.02 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 8350645.00 cycles +P(n): 17.42 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 30609110.00 cycles +P(n): 18.91 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 186796768.00 cycles +P(n): 19.31 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 733212800.00 cycles +P(n): 19.66 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 2960800768.00 cycles +P(n): 19.46 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 18505687040.00 cycles +P(n): 19.46 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 73613836288.00 cycles +P(n): 7.89 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/1.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/1.log new file mode 100644 index 0000000..9eac607 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 3897775.00 cycles +P(n): 9.43 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 13522278.00 cycles +P(n): 10.76 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 50063060.00 cycles +P(n): 11.56 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 240297888.00 cycles +P(n): 15.01 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 942706688.00 cycles +P(n): 15.29 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3722795008.00 cycles +P(n): 15.48 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 22749288448.00 cycles +P(n): 15.83 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 90110476288.00 cycles +P(n): 6.45 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/2.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/2.log new file mode 100644 index 0000000..e61cf75 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 3907767.50 cycles +P(n): 9.40 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 13510660.00 cycles +P(n): 10.77 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 50107380.00 cycles +P(n): 11.55 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 239951200.00 cycles +P(n): 15.03 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 940302272.00 cycles +P(n): 15.33 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3722942720.00 cycles +P(n): 15.48 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 22711234560.00 cycles +P(n): 15.85 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 90064855040.00 cycles +P(n): 6.45 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/3.log b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/3.log new file mode 100644 index 0000000..98b4ec6 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float.cpp ./variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix.cpp -o main_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 3256 bytes +I(n): 56.42 flops/byte +W(n): 36740000.00 flops +T(n): 3864792.00 cycles +P(n): 9.51 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 6456 bytes +I(n): 112.67 flops/byte +W(n): 145480000.00 flops +T(n): 13472545.00 cycles +P(n): 10.80 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 12856 bytes +I(n): 225.17 flops/byte +W(n): 578960000.00 flops +T(n): 49757488.00 cycles +P(n): 11.64 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 562.67 flops/byte +W(n): 3607399936.00 flops +T(n): 238792880.00 cycles +P(n): 15.11 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 1125.17 flops/byte +W(n): 14414799872.00 flops +T(n): 953924224.00 cycles +P(n): 15.11 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 2250.17 flops/byte +W(n): 57629601792.00 flops +T(n): 3701525248.00 cycles +P(n): 15.57 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800369920.00 flops +Q(n) per iteration: 320056 bytes +I(n): 5625.17 flops/byte +W(n): 360073986048.00 flops +T(n): 22775025664.00 cycles +P(n): 15.81 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772800.00 flops +Q(n) per iteration: 640056 bytes +I(n): 4539.87 flops/byte +W(n): 581154570240.00 flops +T(n): 90258751488.00 cycles +P(n): 6.44 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry/x86/2.log b/measurements/variant_float_inlining_SoA_symmetry/x86/2.log new file mode 100644 index 0000000..89a2fd1 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry.cpp -o main_float_inlining_SoA_symmetry -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 20694936.00 cycles +P(n): 0.92 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 81658352.00 cycles +P(n): 0.91 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 334585664.00 cycles +P(n): 0.87 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 2584741888.00 cycles +P(n): 0.70 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 11100169216.00 cycles +P(n): 0.65 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 49019121664.00 cycles +P(n): 0.59 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 351723257856.00 cycles +P(n): 0.51 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry/x86/3.log b/measurements/variant_float_inlining_SoA_symmetry/x86/3.log new file mode 100644 index 0000000..38d9994 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry.cpp -o main_float_inlining_SoA_symmetry -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 20725438.00 cycles +P(n): 0.92 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 81754928.00 cycles +P(n): 0.91 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 334743744.00 cycles +P(n): 0.87 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 2581337088.00 cycles +P(n): 0.70 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 11223846912.00 cycles +P(n): 0.64 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 49533292544.00 cycles +P(n): 0.58 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 350542561280.00 cycles +P(n): 0.51 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry_ILP_16/x86/2.log b/measurements/variant_float_inlining_SoA_symmetry_ILP_16/x86/2.log new file mode 100644 index 0000000..2967098 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry_ILP_16/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry_ILP_16.cpp -o main_float_inlining_SoA_symmetry_ILP_16 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 17928308.00 cycles +P(n): 1.07 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 64051680.00 cycles +P(n): 1.16 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 254104352.00 cycles +P(n): 1.15 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 1873828992.00 cycles +P(n): 0.97 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 8172222976.00 cycles +P(n): 0.88 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 33889355776.00 cycles +P(n): 0.85 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 218516439040.00 cycles +P(n): 0.82 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry_ILP_16/x86/3.log b/measurements/variant_float_inlining_SoA_symmetry_ILP_16/x86/3.log new file mode 100644 index 0000000..a185098 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry_ILP_16/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry_ILP_16.cpp -o main_float_inlining_SoA_symmetry_ILP_16 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 18233164.00 cycles +P(n): 1.05 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 65275440.00 cycles +P(n): 1.14 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 253765520.00 cycles +P(n): 1.15 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 1865975808.00 cycles +P(n): 0.97 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 8123003904.00 cycles +P(n): 0.89 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 33680871424.00 cycles +P(n): 0.86 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 220842590208.00 cycles +P(n): 0.82 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry_ILP_2/x86/2.log b/measurements/variant_float_inlining_SoA_symmetry_ILP_2/x86/2.log new file mode 100644 index 0000000..6ac08be --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry_ILP_2/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry_ILP_2.cpp -o main_float_inlining_SoA_symmetry_ILP_2 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 18636110.00 cycles +P(n): 1.02 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 74353936.00 cycles +P(n): 1.00 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 294626592.00 cycles +P(n): 0.99 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 2190295296.00 cycles +P(n): 0.83 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 9388432384.00 cycles +P(n): 0.77 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 40763506688.00 cycles +P(n): 0.71 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 288141017088.00 cycles +P(n): 0.63 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry_ILP_2/x86/3.log b/measurements/variant_float_inlining_SoA_symmetry_ILP_2/x86/3.log new file mode 100644 index 0000000..6e0974c --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry_ILP_2/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry_ILP_2.cpp -o main_float_inlining_SoA_symmetry_ILP_2 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 18660336.00 cycles +P(n): 1.02 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 72993616.00 cycles +P(n): 1.02 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 293862496.00 cycles +P(n): 1.00 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 2185636352.00 cycles +P(n): 0.83 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 9371756544.00 cycles +P(n): 0.77 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 41083510784.00 cycles +P(n): 0.70 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 287173902336.00 cycles +P(n): 0.63 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry_ILP_4/x86/2.log b/measurements/variant_float_inlining_SoA_symmetry_ILP_4/x86/2.log new file mode 100644 index 0000000..7faa71c --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry_ILP_4/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry_ILP_4.cpp -o main_float_inlining_SoA_symmetry_ILP_4 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 17093748.00 cycles +P(n): 1.12 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 65814740.00 cycles +P(n): 1.13 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 268615712.00 cycles +P(n): 1.09 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 1957872256.00 cycles +P(n): 0.92 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 8319636480.00 cycles +P(n): 0.87 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 35145236480.00 cycles +P(n): 0.82 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 237461798912.00 cycles +P(n): 0.76 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry_ILP_4/x86/3.log b/measurements/variant_float_inlining_SoA_symmetry_ILP_4/x86/3.log new file mode 100644 index 0000000..6d1d221 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry_ILP_4/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry_ILP_4.cpp -o main_float_inlining_SoA_symmetry_ILP_4 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 17023572.00 cycles +P(n): 1.12 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 65836080.00 cycles +P(n): 1.13 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 267259904.00 cycles +P(n): 1.09 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 1952850944.00 cycles +P(n): 0.93 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 8324440064.00 cycles +P(n): 0.87 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 35432906752.00 cycles +P(n): 0.81 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 238751940608.00 cycles +P(n): 0.75 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry_ILP_8/x86/2.log b/measurements/variant_float_inlining_SoA_symmetry_ILP_8/x86/2.log new file mode 100644 index 0000000..36b9d5c --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry_ILP_8/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry_ILP_8.cpp -o main_float_inlining_SoA_symmetry_ILP_8 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 15348080.00 cycles +P(n): 1.24 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 56733160.00 cycles +P(n): 1.31 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 226593312.00 cycles +P(n): 1.29 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 1704302464.00 cycles +P(n): 1.06 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 7344024576.00 cycles +P(n): 0.98 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 31043047424.00 cycles +P(n): 0.93 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 205332381696.00 cycles +P(n): 0.88 flops/cycle + diff --git a/measurements/variant_float_inlining_SoA_symmetry_ILP_8/x86/3.log b/measurements/variant_float_inlining_SoA_symmetry_ILP_8/x86/3.log new file mode 100644 index 0000000..222a7e0 --- /dev/null +++ b/measurements/variant_float_inlining_SoA_symmetry_ILP_8/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-float_symmetry.cpp ./variants/variant_float_inlining_SoA_symmetry_ILP_8.cpp -o main_float_inlining_SoA_symmetry_ILP_8 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 3256 bytes +I(n): 29.33 flops/byte +W(n): 19100000.00 flops +T(n): 15111212.00 cycles +P(n): 1.26 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 6456 bytes +I(n): 57.47 flops/byte +W(n): 74200000.00 flops +T(n): 55873808.00 cycles +P(n): 1.33 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 12856 bytes +I(n): 113.72 flops/byte +W(n): 292400000.00 flops +T(n): 225309888.00 cycles +P(n): 1.30 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 32056 bytes +I(n): 282.47 flops/byte +W(n): 1811000064.00 flops +T(n): 1706010624.00 cycles +P(n): 1.06 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 64056 bytes +I(n): 563.73 flops/byte +W(n): 7222000128.00 flops +T(n): 7389733376.00 cycles +P(n): 0.98 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 128056 bytes +I(n): 1126.23 flops/byte +W(n): 28843999232.00 flops +T(n): 31043899392.00 cycles +P(n): 0.93 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550016.00 flops +Q(n) per iteration: 320056 bytes +I(n): 2813.73 flops/byte +W(n): 180110000128.00 flops +T(n): 205621460992.00 cycles +P(n): 0.88 flops/cycle + diff --git a/measurements/variant_inlining_7/x86/2.log b/measurements/variant_inlining_7/x86/2.log new file mode 100644 index 0000000..ecff983 --- /dev/null +++ b/measurements/variant_inlining_7/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_7.cpp -o main_inlining_7 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 26033530.00 cycles +P(n): 1.41 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 102659900.00 cycles +P(n): 1.42 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 414240760.00 cycles +P(n): 1.40 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 2701176340.00 cycles +P(n): 1.34 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 10897753680.00 cycles +P(n): 1.32 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 44787475960.00 cycles +P(n): 1.29 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 302018381520.00 cycles +P(n): 1.19 flops/cycle + diff --git a/measurements/variant_inlining_7/x86/3.log b/measurements/variant_inlining_7/x86/3.log new file mode 100644 index 0000000..ea2a6b0 --- /dev/null +++ b/measurements/variant_inlining_7/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_7.cpp -o main_inlining_7 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 26177315.00 cycles +P(n): 1.40 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 103020520.00 cycles +P(n): 1.41 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 414208700.00 cycles +P(n): 1.40 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 2684751880.00 cycles +P(n): 1.34 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 10888976120.00 cycles +P(n): 1.32 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 44523656380.00 cycles +P(n): 1.29 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 301445315720.00 cycles +P(n): 1.19 flops/cycle + diff --git a/measurements/variant_inlining_7_SoA/x86/2.log b/measurements/variant_inlining_7_SoA/x86/2.log new file mode 100644 index 0000000..5e198c7 --- /dev/null +++ b/measurements/variant_inlining_7_SoA/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_7_SoA.cpp -o main_inlining_7_SoA -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 35265555.00 cycles +P(n): 1.04 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 135241820.00 cycles +P(n): 1.08 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 568722420.00 cycles +P(n): 1.02 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 3531252960.00 cycles +P(n): 1.02 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 13883478000.00 cycles +P(n): 1.04 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 55083280220.00 cycles +P(n): 1.05 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 339504049100.00 cycles +P(n): 1.06 flops/cycle + diff --git a/measurements/variant_inlining_7_SoA/x86/3.log b/measurements/variant_inlining_7_SoA/x86/3.log new file mode 100644 index 0000000..ee1aa07 --- /dev/null +++ b/measurements/variant_inlining_7_SoA/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_7_SoA.cpp -o main_inlining_7_SoA -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 35315300.00 cycles +P(n): 1.04 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 135382900.00 cycles +P(n): 1.07 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 567506660.00 cycles +P(n): 1.02 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 3508819820.00 cycles +P(n): 1.03 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 13778499800.00 cycles +P(n): 1.05 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 55289505680.00 cycles +P(n): 1.04 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 339702161980.00 cycles +P(n): 1.06 flops/cycle + diff --git a/measurements/variant_inlining_7_SoA_AVX2/x86/3.log b/measurements/variant_inlining_7_SoA_AVX2/x86/3.log new file mode 100644 index 0000000..4303c26 --- /dev/null +++ b/measurements/variant_inlining_7_SoA_AVX2/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_7_SoA_AVX2.cpp -o main_inlining_7_SoA_AVX2 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 16889960.00 cycles +P(n): 2.18 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 57609390.00 cycles +P(n): 2.53 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 220531020.00 cycles +P(n): 2.63 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 1352997020.00 cycles +P(n): 2.67 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 5360580460.00 cycles +P(n): 2.69 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 21347590360.00 cycles +P(n): 2.70 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 119599550780.00 cycles +P(n): 3.01 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 483808876720.00 cycles +P(n): 1.20 flops/cycle + diff --git a/measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/1.log b/measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/1.log new file mode 100644 index 0000000..7ff1112 --- /dev/null +++ b/measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_7_SoA_AVX2_polyexp_expfix.cpp -o main_inlining_7_SoA_AVX2_polyexp_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 11371033.75 cycles +P(n): 3.23 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 39890030.00 cycles +P(n): 3.65 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 153171560.00 cycles +P(n): 3.78 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 926036960.00 cycles +P(n): 3.90 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 3676943300.00 cycles +P(n): 3.92 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 14545721140.00 cycles +P(n): 3.96 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 90702048200.00 cycles +P(n): 3.97 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 362081083160.00 cycles +P(n): 1.61 flops/cycle + diff --git a/measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/2.log b/measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/2.log new file mode 100644 index 0000000..f46ef75 --- /dev/null +++ b/measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/2.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 11368170.00 cycles +P(n): 3.23 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 39909820.00 cycles +P(n): 3.65 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 152279380.00 cycles +P(n): 3.80 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 925130680.00 cycles +P(n): 3.90 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 3668254420.00 cycles +P(n): 3.93 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 14660040260.00 cycles +P(n): 3.93 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 93340296780.00 cycles +P(n): 3.86 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 362367747120.00 cycles +P(n): 1.60 flops/cycle + diff --git a/measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/3.log b/measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/3.log new file mode 100644 index 0000000..25880a8 --- /dev/null +++ b/measurements/variant_inlining_7_SoA_AVX2_polyexp_expfix/x86/3.log @@ -0,0 +1,64 @@ +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 11342471.25 cycles +P(n): 3.24 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 40124180.00 cycles +P(n): 3.63 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 151911440.00 cycles +P(n): 3.81 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 923357200.00 cycles +P(n): 3.91 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 3687447740.00 cycles +P(n): 3.91 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 14732693600.00 cycles +P(n): 3.91 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 90864696480.00 cycles +P(n): 3.96 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 361983172200.00 cycles +P(n): 1.61 flops/cycle + diff --git a/measurements/variant_inlining_7_symmetry_1/x86/2.log b/measurements/variant_inlining_7_symmetry_1/x86/2.log new file mode 100644 index 0000000..92871fc --- /dev/null +++ b/measurements/variant_inlining_7_symmetry_1/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-symmetry.cpp ./variants/variant_inlining_7_symmetry_1.cpp -o main_inlining_7_symmetry_1 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 6512 bytes +I(n): 14.67 flops/byte +W(n): 19100000.00 flops +T(n): 26727245.00 cycles +P(n): 0.71 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 12912 bytes +I(n): 28.73 flops/byte +W(n): 74200000.00 flops +T(n): 103992320.00 cycles +P(n): 0.71 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 25712 bytes +I(n): 56.86 flops/byte +W(n): 292400000.00 flops +T(n): 420016640.00 cycles +P(n): 0.70 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 141.24 flops/byte +W(n): 1811000000.00 flops +T(n): 2777078580.00 cycles +P(n): 0.65 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 281.86 flops/byte +W(n): 7222000000.00 flops +T(n): 11331552620.00 cycles +P(n): 0.64 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 563.11 flops/byte +W(n): 28844000000.00 flops +T(n): 47005533260.00 cycles +P(n): 0.61 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 1406.86 flops/byte +W(n): 180110000000.00 flops +T(n): 207916013360.00 cycles +P(n): 0.87 flops/cycle + diff --git a/measurements/variant_inlining_7_symmetry_1/x86/3.log b/measurements/variant_inlining_7_symmetry_1/x86/3.log new file mode 100644 index 0000000..9f97be0 --- /dev/null +++ b/measurements/variant_inlining_7_symmetry_1/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-symmetry.cpp ./variants/variant_inlining_7_symmetry_1.cpp -o main_inlining_7_symmetry_1 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 6512 bytes +I(n): 14.67 flops/byte +W(n): 19100000.00 flops +T(n): 26767850.00 cycles +P(n): 0.71 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 12912 bytes +I(n): 28.73 flops/byte +W(n): 74200000.00 flops +T(n): 104659680.00 cycles +P(n): 0.71 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 25712 bytes +I(n): 56.86 flops/byte +W(n): 292400000.00 flops +T(n): 421525360.00 cycles +P(n): 0.69 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 141.24 flops/byte +W(n): 1811000000.00 flops +T(n): 2790761980.00 cycles +P(n): 0.65 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 281.86 flops/byte +W(n): 7222000000.00 flops +T(n): 11641782400.00 cycles +P(n): 0.62 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 563.11 flops/byte +W(n): 28844000000.00 flops +T(n): 47106595880.00 cycles +P(n): 0.61 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 1406.86 flops/byte +W(n): 180110000000.00 flops +T(n): 208836888460.00 cycles +P(n): 0.86 flops/cycle + diff --git a/measurements/variant_inlining_7_symmetry_2/x86/2.log b/measurements/variant_inlining_7_symmetry_2/x86/2.log new file mode 100644 index 0000000..4b0911a --- /dev/null +++ b/measurements/variant_inlining_7_symmetry_2/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-symmetry.cpp ./variants/variant_inlining_7_symmetry_2.cpp -o main_inlining_7_symmetry_2 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 6512 bytes +I(n): 14.67 flops/byte +W(n): 19100000.00 flops +T(n): 26562245.00 cycles +P(n): 0.72 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 12912 bytes +I(n): 28.73 flops/byte +W(n): 74200000.00 flops +T(n): 103075420.00 cycles +P(n): 0.72 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 25712 bytes +I(n): 56.86 flops/byte +W(n): 292400000.00 flops +T(n): 418508180.00 cycles +P(n): 0.70 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 141.24 flops/byte +W(n): 1811000000.00 flops +T(n): 2778344240.00 cycles +P(n): 0.65 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 281.86 flops/byte +W(n): 7222000000.00 flops +T(n): 11360649140.00 cycles +P(n): 0.64 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 563.11 flops/byte +W(n): 28844000000.00 flops +T(n): 46979623260.00 cycles +P(n): 0.61 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 1406.86 flops/byte +W(n): 180110000000.00 flops +T(n): 208094812200.00 cycles +P(n): 0.87 flops/cycle + diff --git a/measurements/variant_inlining_7_symmetry_2/x86/3.log b/measurements/variant_inlining_7_symmetry_2/x86/3.log new file mode 100644 index 0000000..4cab342 --- /dev/null +++ b/measurements/variant_inlining_7_symmetry_2/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-symmetry.cpp ./variants/variant_inlining_7_symmetry_2.cpp -o main_inlining_7_symmetry_2 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 6512 bytes +I(n): 14.67 flops/byte +W(n): 19100000.00 flops +T(n): 26620640.00 cycles +P(n): 0.72 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 12912 bytes +I(n): 28.73 flops/byte +W(n): 74200000.00 flops +T(n): 103702040.00 cycles +P(n): 0.72 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 25712 bytes +I(n): 56.86 flops/byte +W(n): 292400000.00 flops +T(n): 417450420.00 cycles +P(n): 0.70 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 141.24 flops/byte +W(n): 1811000000.00 flops +T(n): 2785555280.00 cycles +P(n): 0.65 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 281.86 flops/byte +W(n): 7222000000.00 flops +T(n): 11343649360.00 cycles +P(n): 0.64 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 563.11 flops/byte +W(n): 28844000000.00 flops +T(n): 46953691640.00 cycles +P(n): 0.61 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 1406.86 flops/byte +W(n): 180110000000.00 flops +T(n): 207442349960.00 cycles +P(n): 0.87 flops/cycle + diff --git a/measurements/variant_inlining_7_symmetry_2_ilp_1/x86/2.log b/measurements/variant_inlining_7_symmetry_2_ilp_1/x86/2.log new file mode 100644 index 0000000..979c643 --- /dev/null +++ b/measurements/variant_inlining_7_symmetry_2_ilp_1/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-symmetry.cpp ./variants/variant_inlining_7_symmetry_2_ilp_1.cpp -o main_inlining_7_symmetry_2_ilp_1 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 6512 bytes +I(n): 14.67 flops/byte +W(n): 19100000.00 flops +T(n): 26434750.00 cycles +P(n): 0.72 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 12912 bytes +I(n): 28.73 flops/byte +W(n): 74200000.00 flops +T(n): 103076140.00 cycles +P(n): 0.72 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 25712 bytes +I(n): 56.86 flops/byte +W(n): 292400000.00 flops +T(n): 414752620.00 cycles +P(n): 0.70 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 141.24 flops/byte +W(n): 1811000000.00 flops +T(n): 2727126060.00 cycles +P(n): 0.66 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 281.86 flops/byte +W(n): 7222000000.00 flops +T(n): 11087200940.00 cycles +P(n): 0.65 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 563.11 flops/byte +W(n): 28844000000.00 flops +T(n): 45051280280.00 cycles +P(n): 0.64 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 1406.86 flops/byte +W(n): 180110000000.00 flops +T(n): 210209411220.00 cycles +P(n): 0.86 flops/cycle + diff --git a/measurements/variant_inlining_7_symmetry_2_ilp_1/x86/3.log b/measurements/variant_inlining_7_symmetry_2_ilp_1/x86/3.log new file mode 100644 index 0000000..d2f263a --- /dev/null +++ b/measurements/variant_inlining_7_symmetry_2_ilp_1/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-symmetry.cpp ./variants/variant_inlining_7_symmetry_2_ilp_1.cpp -o main_inlining_7_symmetry_2_ilp_1 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 6512 bytes +I(n): 14.67 flops/byte +W(n): 19100000.00 flops +T(n): 26387870.00 cycles +P(n): 0.72 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 12912 bytes +I(n): 28.73 flops/byte +W(n): 74200000.00 flops +T(n): 102030060.00 cycles +P(n): 0.73 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 25712 bytes +I(n): 56.86 flops/byte +W(n): 292400000.00 flops +T(n): 414172500.00 cycles +P(n): 0.71 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 141.24 flops/byte +W(n): 1811000000.00 flops +T(n): 2720855140.00 cycles +P(n): 0.67 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 281.86 flops/byte +W(n): 7222000000.00 flops +T(n): 11113087680.00 cycles +P(n): 0.65 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 563.11 flops/byte +W(n): 28844000000.00 flops +T(n): 44960698300.00 cycles +P(n): 0.64 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 1406.86 flops/byte +W(n): 180110000000.00 flops +T(n): 208987223120.00 cycles +P(n): 0.86 flops/cycle + diff --git a/measurements/variant_inlining_7_symmetry_2_ilp_2/x86/2.log b/measurements/variant_inlining_7_symmetry_2_ilp_2/x86/2.log new file mode 100644 index 0000000..260ce44 --- /dev/null +++ b/measurements/variant_inlining_7_symmetry_2_ilp_2/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-symmetry.cpp ./variants/variant_inlining_7_symmetry_2_ilp_2.cpp -o main_inlining_7_symmetry_2_ilp_2 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 6512 bytes +I(n): 14.67 flops/byte +W(n): 19100000.00 flops +T(n): 26819620.00 cycles +P(n): 0.71 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 12912 bytes +I(n): 28.73 flops/byte +W(n): 74200000.00 flops +T(n): 105029000.00 cycles +P(n): 0.71 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 25712 bytes +I(n): 56.86 flops/byte +W(n): 292400000.00 flops +T(n): 423715960.00 cycles +P(n): 0.69 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 141.24 flops/byte +W(n): 1811000000.00 flops +T(n): 2769934960.00 cycles +P(n): 0.65 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 281.86 flops/byte +W(n): 7222000000.00 flops +T(n): 11885758320.00 cycles +P(n): 0.61 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 563.11 flops/byte +W(n): 28844000000.00 flops +T(n): 48235104920.00 cycles +P(n): 0.60 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 1406.86 flops/byte +W(n): 180110000000.00 flops +T(n): 317460685280.00 cycles +P(n): 0.57 flops/cycle + diff --git a/measurements/variant_inlining_7_symmetry_2_ilp_2/x86/3.log b/measurements/variant_inlining_7_symmetry_2_ilp_2/x86/3.log new file mode 100644 index 0000000..95972c7 --- /dev/null +++ b/measurements/variant_inlining_7_symmetry_2_ilp_2/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main-symmetry.cpp ./variants/variant_inlining_7_symmetry_2_ilp_2.cpp -o main_inlining_7_symmetry_2_ilp_2 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 95500.00 flops +Q(n) per iteration: 6512 bytes +I(n): 14.67 flops/byte +W(n): 19100000.00 flops +T(n): 26682785.00 cycles +P(n): 0.72 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 371000.00 flops +Q(n) per iteration: 12912 bytes +I(n): 28.73 flops/byte +W(n): 74200000.00 flops +T(n): 103925380.00 cycles +P(n): 0.71 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 1462000.00 flops +Q(n) per iteration: 25712 bytes +I(n): 56.86 flops/byte +W(n): 292400000.00 flops +T(n): 415782740.00 cycles +P(n): 0.70 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 9055000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 141.24 flops/byte +W(n): 1811000000.00 flops +T(n): 2735007900.00 cycles +P(n): 0.66 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 36110000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 281.86 flops/byte +W(n): 7222000000.00 flops +T(n): 11240995220.00 cycles +P(n): 0.64 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 144220000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 563.11 flops/byte +W(n): 28844000000.00 flops +T(n): 46790666220.00 cycles +P(n): 0.62 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 900550000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 1406.86 flops/byte +W(n): 180110000000.00 flops +T(n): 308031751960.00 cycles +P(n): 0.58 flops/cycle + diff --git a/measurements/variant_inlining_8/x86/2.log b/measurements/variant_inlining_8/x86/2.log new file mode 100644 index 0000000..3a83c82 --- /dev/null +++ b/measurements/variant_inlining_8/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8.cpp -o main_inlining_8 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 25924030.00 cycles +P(n): 1.42 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 103751840.00 cycles +P(n): 1.40 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 414349600.00 cycles +P(n): 1.40 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 2738371940.00 cycles +P(n): 1.32 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 10966457560.00 cycles +P(n): 1.31 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 44694972240.00 cycles +P(n): 1.29 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 303613890420.00 cycles +P(n): 1.19 flops/cycle + diff --git a/measurements/variant_inlining_8/x86/3.log b/measurements/variant_inlining_8/x86/3.log new file mode 100644 index 0000000..ff35d11 --- /dev/null +++ b/measurements/variant_inlining_8/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8.cpp -o main_inlining_8 -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 25871680.00 cycles +P(n): 1.42 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 101682420.00 cycles +P(n): 1.43 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 411536620.00 cycles +P(n): 1.41 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 2678464020.00 cycles +P(n): 1.35 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 10860602260.00 cycles +P(n): 1.33 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 44447633220.00 cycles +P(n): 1.30 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 301546448660.00 cycles +P(n): 1.19 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/1.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/1.log new file mode 100644 index 0000000..b741ee1 --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8339301.25 cycles +P(n): 4.41 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 28662660.00 cycles +P(n): 5.08 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 104402900.00 cycles +P(n): 5.55 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 636519040.00 cycles +P(n): 5.67 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2499027620.00 cycles +P(n): 5.77 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9941452140.00 cycles +P(n): 5.80 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 61650558000.00 cycles +P(n): 5.84 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 246792591620.00 cycles +P(n): 2.35 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/2.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/2.log new file mode 100644 index 0000000..5762311 --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8445907.50 cycles +P(n): 4.35 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 28691310.00 cycles +P(n): 5.07 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 104933160.00 cycles +P(n): 5.52 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 639568720.00 cycles +P(n): 5.64 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2515964020.00 cycles +P(n): 5.73 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9996713720.00 cycles +P(n): 5.76 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 62098746740.00 cycles +P(n): 5.80 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 247013435860.00 cycles +P(n): 2.35 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/3.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/3.log new file mode 100644 index 0000000..f95f05f --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8335317.50 cycles +P(n): 4.41 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 28557990.00 cycles +P(n): 5.09 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 104404360.00 cycles +P(n): 5.55 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 635858120.00 cycles +P(n): 5.67 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2509183840.00 cycles +P(n): 5.74 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9956726160.00 cycles +P(n): 5.79 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 61839346220.00 cycles +P(n): 5.82 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 246699025260.00 cycles +P(n): 2.36 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/1.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/1.log new file mode 100644 index 0000000..18b6f5f --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8308587.50 cycles +P(n): 4.42 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 28404470.00 cycles +P(n): 5.12 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 103978120.00 cycles +P(n): 5.57 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 633362280.00 cycles +P(n): 5.70 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2494262100.00 cycles +P(n): 5.78 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9899453320.00 cycles +P(n): 5.82 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 61865956520.00 cycles +P(n): 5.82 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 246306063920.00 cycles +P(n): 2.36 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/2.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/2.log new file mode 100644 index 0000000..1653c69 --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8344811.25 cycles +P(n): 4.40 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 28520365.00 cycles +P(n): 5.10 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 104404120.00 cycles +P(n): 5.55 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 636400560.00 cycles +P(n): 5.67 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2501258800.00 cycles +P(n): 5.76 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9901533780.00 cycles +P(n): 5.82 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 61815669960.00 cycles +P(n): 5.82 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 247091597180.00 cycles +P(n): 2.35 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/3.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/3.log new file mode 100644 index 0000000..a60b0dc --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8321530.00 cycles +P(n): 4.42 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 28458355.00 cycles +P(n): 5.11 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 104209360.00 cycles +P(n): 5.56 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 634333640.00 cycles +P(n): 5.69 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2496796020.00 cycles +P(n): 5.77 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9914787460.00 cycles +P(n): 5.81 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 61721090840.00 cycles +P(n): 5.83 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 246519066200.00 cycles +P(n): 2.36 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/1.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/1.log new file mode 100644 index 0000000..c33cf4f --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_moreavx_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 7985528.75 cycles +P(n): 4.60 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 27703355.00 cycles +P(n): 5.25 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 102292560.00 cycles +P(n): 5.66 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 629804220.00 cycles +P(n): 5.73 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2472263180.00 cycles +P(n): 5.83 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9851588140.00 cycles +P(n): 5.85 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 61479499820.00 cycles +P(n): 5.86 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 245617006060.00 cycles +P(n): 2.37 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/2.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/2.log new file mode 100644 index 0000000..5ee8171 --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_moreavx_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8028216.25 cycles +P(n): 4.58 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 27833730.00 cycles +P(n): 5.23 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 102829680.00 cycles +P(n): 5.63 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 629698060.00 cycles +P(n): 5.73 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2469782600.00 cycles +P(n): 5.84 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9826240720.00 cycles +P(n): 5.86 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 61490138600.00 cycles +P(n): 5.86 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 245848977420.00 cycles +P(n): 2.36 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/3.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/3.log new file mode 100644 index 0000000..27a1fc5 --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_moreavx_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 7992830.00 cycles +P(n): 4.60 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 27693680.00 cycles +P(n): 5.25 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 102340840.00 cycles +P(n): 5.66 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 638328340.00 cycles +P(n): 5.65 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2468865800.00 cycles +P(n): 5.84 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9838254540.00 cycles +P(n): 5.86 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 61344519940.00 cycles +P(n): 5.87 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 245174501540.00 cycles +P(n): 2.37 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/1.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/1.log new file mode 100644 index 0000000..7a9a201 --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/1.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8506121.25 cycles +P(n): 4.32 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 27681145.00 cycles +P(n): 5.26 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 98048030.00 cycles +P(n): 5.90 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 594320700.00 cycles +P(n): 6.07 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2270890500.00 cycles +P(n): 6.35 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 8985906260.00 cycles +P(n): 6.41 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 56358587540.00 cycles +P(n): 6.39 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 224065475420.00 cycles +P(n): 2.59 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/2.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/2.log new file mode 100644 index 0000000..e6443dc --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/2.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8512763.75 cycles +P(n): 4.32 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 27679115.00 cycles +P(n): 5.26 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 98109310.00 cycles +P(n): 5.90 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 583896260.00 cycles +P(n): 6.18 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2292138700.00 cycles +P(n): 6.29 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 9006037600.00 cycles +P(n): 6.40 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 56211721500.00 cycles +P(n): 6.41 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 223879818840.00 cycles +P(n): 2.60 flops/cycle + diff --git a/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/3.log b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/3.log new file mode 100644 index 0000000..c702109 --- /dev/null +++ b/measurements/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix/x86/3.log @@ -0,0 +1,66 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp -o main_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 8550285.00 cycles +P(n): 4.30 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 27834905.00 cycles +P(n): 5.23 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 98660270.00 cycles +P(n): 5.87 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 587210580.00 cycles +P(n): 6.14 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 2280133880.00 cycles +P(n): 6.32 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 8974668040.00 cycles +P(n): 6.42 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 56052905260.00 cycles +P(n): 6.42 flops/cycle + +=== N_P=10000 N_ITER=200 === +W(n) per iteration: 2905772704.00 flops +Q(n) per iteration: 1280112 bytes +I(n): 2269.94 flops/byte +W(n): 581154540800.00 flops +T(n): 224433219680.00 cycles +P(n): 2.59 flops/cycle + diff --git a/measurements/variant_lut_exp/x86/2.log b/measurements/variant_lut_exp/x86/2.log new file mode 100644 index 0000000..82f5137 --- /dev/null +++ b/measurements/variant_lut_exp/x86/2.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_lut_exp.cpp -o main_lut_exp -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 28659980.00 cycles +P(n): 1.28 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 108522660.00 cycles +P(n): 1.34 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 435222760.00 cycles +P(n): 1.33 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 2907689920.00 cycles +P(n): 1.24 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 11907431920.00 cycles +P(n): 1.21 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 47838796500.00 cycles +P(n): 1.20 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 305274270720.00 cycles +P(n): 1.18 flops/cycle + diff --git a/measurements/variant_lut_exp/x86/3.log b/measurements/variant_lut_exp/x86/3.log new file mode 100644 index 0000000..bb31ac2 --- /dev/null +++ b/measurements/variant_lut_exp/x86/3.log @@ -0,0 +1,58 @@ +rm -f main_* run_tests *.o *.s variants/*.s variants/*.o headers/*.s headers/*.o +/usr/bin/g++ main.cpp ./variants/variant_lut_exp.cpp -o main_lut_exp -O3 -march=native -std=c++23 -Wall -Wextra -flto -DFLOPCOUNT=0 -DRANDOM_SEED=0 -DROOFLINE=0 -DBENCHMARK=1 +=== N_P=50 N_ITER=200 === +W(n) per iteration: 183700.00 flops +Q(n) per iteration: 6512 bytes +I(n): 28.21 flops/byte +W(n): 36740000.00 flops +T(n): 28650585.00 cycles +P(n): 1.28 flops/cycle + +=== N_P=100 N_ITER=200 === +W(n) per iteration: 727400.00 flops +Q(n) per iteration: 12912 bytes +I(n): 56.34 flops/byte +W(n): 145480000.00 flops +T(n): 109151460.00 cycles +P(n): 1.33 flops/cycle + +=== N_P=200 N_ITER=200 === +W(n) per iteration: 2894800.00 flops +Q(n) per iteration: 25712 bytes +I(n): 112.59 flops/byte +W(n): 578960000.00 flops +T(n): 436914960.00 cycles +P(n): 1.33 flops/cycle + +=== N_P=500 N_ITER=200 === +W(n) per iteration: 18037000.00 flops +Q(n) per iteration: 64112 bytes +I(n): 281.34 flops/byte +W(n): 3607400000.00 flops +T(n): 2895243380.00 cycles +P(n): 1.25 flops/cycle + +=== N_P=1000 N_ITER=200 === +W(n) per iteration: 72074000.00 flops +Q(n) per iteration: 128112 bytes +I(n): 562.59 flops/byte +W(n): 14414800000.00 flops +T(n): 11815027680.00 cycles +P(n): 1.22 flops/cycle + +=== N_P=2000 N_ITER=200 === +W(n) per iteration: 288148000.00 flops +Q(n) per iteration: 256112 bytes +I(n): 1125.09 flops/byte +W(n): 57629600000.00 flops +T(n): 47796189940.00 cycles +P(n): 1.21 flops/cycle + +=== N_P=5000 N_ITER=200 === +W(n) per iteration: 1800370000.00 flops +Q(n) per iteration: 640112 bytes +I(n): 2812.59 flops/byte +W(n): 360074000000.00 flops +T(n): 304323811480.00 cycles +P(n): 1.18 flops/cycle + diff --git a/scripts/mem-bench.sh b/scripts/mem-bench.sh index afce0e0..4e49d42 100755 --- a/scripts/mem-bench.sh +++ b/scripts/mem-bench.sh @@ -1 +1,11 @@ -sudo sysbench memory --memory-block-size=1G --memory-total-size=20G --memory-oper=read run +#!/bin/bash + +ARCH="x86" +if uname -m | grep -q "arm\|aarch64"; then + ARCH="arm" +fi + +LOGICAL_CORE_COUNT=$(grep ^cpu\\scores /proc/cpuinfo | uniq | awk '{print $4}') +for run in {1..100}; do + sudo sysbench memory --memory-block-size=1G --memory-total-size=20G --memory-oper=read --threads=$LOGICAL_CORE_COUNT run > measurements/memory/$ARCH/$run.log +done diff --git a/variants/variant_AVX512_1_flopcount.cpp b/variants/variant_AVX512_1_flopcount.cpp new file mode 100644 index 0000000..718ee9f --- /dev/null +++ b/variants/variant_AVX512_1_flopcount.cpp @@ -0,0 +1,568 @@ +// # This file attempts to use AVX-512 intrinsics to speed up computation. +// # Predecessor: variant_inlining_7.cpp +#ifdef __AVX512F__ + +#include "../headers/board_reduced.hpp" +#include "../headers/constants.hpp" +#include "../headers/pedestrian_reduced.hpp" + +#include "immintrin.h" +#include "sleef.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0 +#define BOARD_LENGTH 50.0 +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0f +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5f +#define WALL_EPS 1e-3 +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999 + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + Pedestrian *P = new Pedestrian[n_p]; + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + double x = x_gen_left(gen); + double y = y_gen(gen); + + double start_pos_x = x; + double start_pos_y = y; + + double destination_x = BOARD_LENGTH + 30.0; + double destination_y = y; + + double init_e_x = destination_x - start_pos_x; + double init_e_y = destination_y - start_pos_y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + double v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(0, 0, 0, start_pos_x, start_pos_y, init_e_unit_x, init_e_unit_y, v_max, desired_v0, destination_x, destination_y); + } + + for (int i = n_p_half; i < n_p; i++) { + double x = x_gen_right(gen); + double y = y_gen(gen); + + double start_pos_x = x; + double start_pos_y = y; + double destination_x = -30; + double destination_y = y; + + double init_e_x = destination_x - start_pos_x; + double init_e_y = destination_y - start_pos_y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + double v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(1, 0, 0, start_pos_x, start_pos_y, init_e_unit_x, init_e_unit_y, v_max, desired_v0, destination_x, destination_y); + } + + return P; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + samples.emplace_back(0, i, p.curr_pos_x, p.curr_pos_y, p.e_x, p.e_y, p.color); + } + } +#endif + + // # ADDs: n_iter * n_p * 4 + + // # n_iter * n_p * ceil(((double) (n_p - 7)) / 8) * (1 / (ceil(((double) (n_p - 7)) / 8))) * 7 * 14 + + // # n_iter * n_p * ceil(((double) (n_p - 7)) / 8) * (1 - 1 / (ceil(((double) (n_p - 7)) / 8))) * 224 + + // # n_iter * n_p * (n_p - floor((double) n_p / 8) * 8) * 14 + + // # n_iter * n_p * board.n_obstacles * 12 + + // # n_iter * n_p * 7 + + // # MULTs: n_iter * n_p * 4 + + // # n_iter * n_p * ceil(((double) (n_p - 7)) / 8) * (1 / (ceil(((double) (n_p - 7)) / 8))) * 7 * 24 + + // # n_iter * n_p * ceil(((double) (n_p - 7)) / 8) * (1 - 1 / (ceil(((double) (n_p - 7)) / 8))) * 352 + + // # n_iter * n_p * (n_p - floor((double) n_p / 8) * 8) * 24 + + // # n_iter * n_p * board.n_obstacles * 19 + + // # n_iter * n_p * 17 + + // # DIVs: n_iter * n_p * ceil(((double) (n_p - 7)) / 8) * (1 / (ceil(((double) (n_p - 7)) / 8))) * 7 + + // # n_iter * n_p * ceil(((double) (n_p - 7)) / 8) * (1 - 1 / (ceil(((double) (n_p - 7)) / 8))) * 8 + + // # n_iter * n_p * (n_p - floor((double) n_p / 8) * 8) + + // # n_iter * n_p * board.n_obstacles + + // # n_iter * n_p * 2 + + // # SQRTs: n_iter * n_p * ceil(((double) (n_p - 7)) / 8) * (1 / (ceil(((double) (n_p - 7)) / 8))) * 7 * 3 + + // # n_iter * n_p * ceil(((double) (n_p - 7)) / 8) * (1 - 1 / (ceil(((double) (n_p - 7)) / 8))) * 24 + + // # n_iter * n_p * (n_p - floor((double) n_p / 8) * 8) * 3 + + // # n_iter * n_p * board.n_obstacles + + // # n_iter * n_p * 3 + + // # EXPs: n_iter * n_p * ceil(((double) (n_p - 7)) / 8) * (1 / (ceil(((double) (n_p - 7)) / 8))) * 7 + + // # n_iter * n_p * (n_p - floor((double) n_p / 8) * 8) + + // # n_iter * n_p * board.n_obstacles + + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 2 MULTs + double desired_velocity_x = p.e_x * p.desired_v0; + double desired_velocity_y = p.e_y * p.desired_v0; + + // # 2 ADDs, 2 MULTs + double f_alpha_dt_x = (desired_velocity_x - p.curr_vel_x) * dt_times_tau_alpha_inv; + double f_alpha_dt_y = (desired_velocity_y - p.curr_vel_y) * dt_times_tau_alpha_inv; + + __m512d desired_velocity_x_vec = _mm512_set1_pd(desired_velocity_x); + __m512d desired_velocity_y_vec = _mm512_set1_pd(desired_velocity_y); + __m512d f_alpha_dt_x_vec = _mm512_set1_pd(f_alpha_dt_x); + __m512d f_alpha_dt_y_vec = _mm512_set1_pd(f_alpha_dt_y); + + __m512d alpha_curr_pos_x_vec = _mm512_set1_pd(p.curr_pos_x); + __m512d alpha_curr_pos_y_vec = _mm512_set1_pd(p.curr_pos_y); + __m512d alpha_e_x_vec = _mm512_set1_pd(p.e_x); + __m512d alpha_e_y_vec = _mm512_set1_pd(p.e_y); + + int j; + + // # ############################################################################################################################################################################################ + + for (j = 0; j < n_p - 7; j += 8) { + + if (j <= i && i <= j + 7) { + + for (int jj = j; jj < j + 8; jj++) { + + if (jj == i) { + continue; + } + + // # 2 ADDs + double r_ab_x = p.curr_pos_x - pedestrians[jj].curr_pos_x; + double r_ab_y = p.curr_pos_y - pedestrians[jj].curr_pos_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_ab_norm = sqrt(r_ab_x * r_ab_x + r_ab_y * r_ab_y); + + // # 2 ADDs + double r_ab2_x = r_ab_x - pedestrians[jj].s_b_e_x; + double r_ab2_y = r_ab_y - pedestrians[jj].s_b_e_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_ab2_norm = sqrt(r_ab2_x * r_ab2_x + r_ab2_y * r_ab2_y); + + // # 2 ADDs, 1 MULT + double r_ab_norm_sum = r_ab_norm + r_ab2_norm; + double two_b_sq = r_ab_norm_sum * r_ab_norm_sum - pedestrians[jj].s_b_sq; + + // # 1 SQRT + double two_b = sqrt(two_b_sq); + + // # 5 MULTs, 1 DIV, 1 EXP + double scalar_mult_common = (r_ab_norm_sum / (two_b * r_ab_norm * r_ab2_norm)) * (NEG_V0_AB_div_TWO_SIGMA * exp(two_b * NEG_TWO_SIGMA_INV)); + + // # 2 MULTs + double scalar_mult_r_ab = scalar_mult_common * r_ab2_norm; + double scalar_mult_r_ab2 = scalar_mult_common * r_ab_norm; + + // # 4 MULTs, 2 ADDs + double f_alpha_beta_neg_x = r_ab_x * scalar_mult_r_ab + r_ab2_x * scalar_mult_r_ab2; + double f_alpha_beta_neg_y = r_ab_y * scalar_mult_r_ab + r_ab2_y * scalar_mult_r_ab2; + + double w_val; + + // # 3 MULTs, 1 ADD + double a = (p.e_x * f_alpha_beta_neg_x + p.e_y * f_alpha_beta_neg_y) * cos_phi_inv; + + // # 2 MULTs, 1 ADD + double b_sq = f_alpha_beta_neg_x * f_alpha_beta_neg_x + f_alpha_beta_neg_y * f_alpha_beta_neg_y; + + w_val = dt_neg; + // # 1 MULT + if (a >= 0 && (a * a > b_sq)) { + w_val = c_neg_times_dt; + } + + // # 2 MULTs, 2 ADDs + f_alpha_dt_x = f_alpha_dt_x + f_alpha_beta_neg_x * w_val; + f_alpha_dt_y = f_alpha_dt_y + f_alpha_beta_neg_y * w_val; + } + + } else { + __m512d beta_curr_pos_x_vec = _mm512_setr_pd(pedestrians[j].curr_pos_x, pedestrians[j + 1].curr_pos_x, pedestrians[j + 2].curr_pos_x, pedestrians[j + 3].curr_pos_x, pedestrians[j + 4].curr_pos_x, pedestrians[j + 5].curr_pos_x, pedestrians[j + 6].curr_pos_x, pedestrians[j + 7].curr_pos_x); + __m512d beta_curr_pos_y_vec = _mm512_setr_pd(pedestrians[j].curr_pos_y, pedestrians[j + 1].curr_pos_y, pedestrians[j + 2].curr_pos_y, pedestrians[j + 3].curr_pos_y, pedestrians[j + 4].curr_pos_y, pedestrians[j + 5].curr_pos_y, pedestrians[j + 6].curr_pos_y, pedestrians[j + 7].curr_pos_y); + + // # 16 ADDs + __m512d r_ab_x_vec = _mm512_sub_pd(alpha_curr_pos_x_vec, beta_curr_pos_x_vec); + __m512d r_ab_y_vec = _mm512_sub_pd(alpha_curr_pos_y_vec, beta_curr_pos_y_vec); + + // # 8 MULTs + __m512d r_ab_y_mul_r_ab_y_vec = _mm512_mul_pd(r_ab_y_vec, r_ab_y_vec); + + // # 8 MULTs, 8 ADDs + __m512d r_ab_norm_sq_vec = _mm512_fmadd_pd(r_ab_x_vec, r_ab_x_vec, r_ab_y_mul_r_ab_y_vec); + + // # 8 SQRTs + __m512d r_ab_norm_vec = _mm512_sqrt_pd(r_ab_norm_sq_vec); + + __m512d beta_s_b_e_x_vec = _mm512_setr_pd(pedestrians[j].s_b_e_x, pedestrians[j + 1].s_b_e_x, pedestrians[j + 2].s_b_e_x, pedestrians[j + 3].s_b_e_x, pedestrians[j + 4].s_b_e_x, pedestrians[j + 5].s_b_e_x, pedestrians[j + 6].s_b_e_x, pedestrians[j + 7].s_b_e_x); + + // # 8 ADDs + __m512d r_ab2_x_vec = _mm512_sub_pd(r_ab_x_vec, beta_s_b_e_x_vec); + + __m512d beta_s_b_e_y_vec = _mm512_setr_pd(pedestrians[j].s_b_e_y, pedestrians[j + 1].s_b_e_y, pedestrians[j + 2].s_b_e_y, pedestrians[j + 3].s_b_e_y, pedestrians[j + 4].s_b_e_y, pedestrians[j + 5].s_b_e_y, pedestrians[j + 6].s_b_e_y, pedestrians[j + 7].s_b_e_y); + + // # 8 ADDs + __m512d r_ab2_y_vec = _mm512_sub_pd(r_ab_y_vec, beta_s_b_e_y_vec); + + // # 8 MULTs + __m512d r_ab2_y_mul_r_ab2_y_vec = _mm512_mul_pd(r_ab2_y_vec, r_ab2_y_vec); + + // # 8 MULTs, 8 ADDs + __m512d r_ab2_norm_sq_vec = _mm512_fmadd_pd(r_ab2_x_vec, r_ab2_x_vec, r_ab2_y_mul_r_ab2_y_vec); + + // # 8 SQRTs + __m512d r_ab2_norm_vec = _mm512_sqrt_pd(r_ab2_norm_sq_vec); + + // # 8 ADDs + __m512d r_ab_norm_sum_vec = _mm512_add_pd(r_ab_norm_vec, r_ab2_norm_vec); + + __m512d beta_s_b_sq_vec = _mm512_setr_pd(pedestrians[j].s_b_sq, pedestrians[j + 1].s_b_sq, pedestrians[j + 2].s_b_sq, pedestrians[j + 3].s_b_sq, pedestrians[j + 4].s_b_sq, pedestrians[j + 5].s_b_sq, pedestrians[j + 6].s_b_sq, pedestrians[j + 7].s_b_sq); + + // # 8 MULTs, 8 ADDs + __m512d two_b_sq_vec = _mm512_fmsub_pd(r_ab_norm_sum_vec, r_ab_norm_sum_vec, beta_s_b_sq_vec); + + // # 8 SQRTs + __m512d two_b_vec = _mm512_sqrt_pd(two_b_sq_vec); + + // # 8 MULTs + __m512d two_b_mul_r_ab_norm_vec = _mm512_mul_pd(two_b_vec, r_ab_norm_vec); + + // # 8 MULTs + __m512d denom_vec = _mm512_mul_pd(two_b_mul_r_ab_norm_vec, r_ab2_norm_vec); + + // # 8 DIVs + __m512d scalar_mult_common_left_vec = _mm512_div_pd(r_ab_norm_sum_vec, denom_vec); + + // # 8 MULTs + __m512d two_b_mul_NEG_TWO_SIGMA_INV_vec = _mm512_mul_pd(two_b_vec, NEG_TWO_SIGMA_INV_VEC); + + // # 160 MULTs, 112 ADDs + // objdump -d --demangle /usr/lib/x86_64-linux-gnu/libsleef.so | grep -A 67 "Sleef_expd8_u10@@Base" + __m512d e_vec = Sleef_expd8_u10(two_b_mul_NEG_TWO_SIGMA_INV_vec); + + // # 16 MULTs + __m512d scalar_mult_common_right_vec = _mm512_mul_pd(NEG_V0_AB_DIV_TWO_SIGMA_VEC, e_vec); + __m512d scalar_mult_common_vec = _mm512_mul_pd(scalar_mult_common_left_vec, scalar_mult_common_right_vec); + + // # 16 MULTs + __m512d scalar_mult_r_ab_vec = _mm512_mul_pd(scalar_mult_common_vec, r_ab2_norm_vec); + __m512d scalar_mult_r_ab2_vec = _mm512_mul_pd(scalar_mult_common_vec, r_ab_norm_vec); + + // # 16 MULTs + __m512d r_ab2_x_mul_scalar_mult_r_ab2_vec = _mm512_mul_pd(r_ab2_x_vec, scalar_mult_r_ab2_vec); + __m512d r_ab2_y_mul_scalar_mult_r_ab2_vec = _mm512_mul_pd(r_ab2_y_vec, scalar_mult_r_ab2_vec); + + // # 16 MULTs, 16 ADDs + __m512d f_alpha_beta_neg_x_vec = _mm512_fmadd_pd(r_ab_x_vec, scalar_mult_r_ab_vec, r_ab2_x_mul_scalar_mult_r_ab2_vec); + __m512d f_alpha_beta_neg_y_vec = _mm512_fmadd_pd(r_ab_y_vec, scalar_mult_r_ab_vec, r_ab2_y_mul_scalar_mult_r_ab2_vec); + + // # 8 MULTs + __m512d rgt_vec = _mm512_mul_pd(alpha_e_y_vec, f_alpha_beta_neg_y_vec); + + // # 8 MULTs, 8 ADDs + __m512d lft_add_rgt_vec = _mm512_fmadd_pd(alpha_e_x_vec, f_alpha_beta_neg_x_vec, rgt_vec); + + // # 8 MULTs + __m512d a_vec = _mm512_mul_pd(lft_add_rgt_vec, cos_phi_inv_vec); + + // # 8 MULTs + __m512d f_alpha_beta_neg_y_sq_vec = _mm512_mul_pd(f_alpha_beta_neg_y_vec, f_alpha_beta_neg_y_vec); + + // # 8 MULTs, 8 ADDs + __m512d b_sq_vec = _mm512_fmadd_pd(f_alpha_beta_neg_x_vec, f_alpha_beta_neg_x_vec, f_alpha_beta_neg_y_sq_vec); + + __m512d w_val_vec = dt_neg_vec; + __mmask8 a_ge_zero_mask = _mm512_cmp_pd_mask(a_vec, ZERO_VEC, _CMP_GE_OQ); + + // # 8 MULTs + __m512d a_sq_vec = _mm512_mul_pd(a_vec, a_vec); + + __mmask8 a_sq_gt_b_sq_mask = _mm512_cmp_pd_mask(a_sq_vec, b_sq_vec, _CMP_GT_OQ); + __mmask8 cond_mask = _kand_mask8(a_ge_zero_mask, a_sq_gt_b_sq_mask); + w_val_vec = _mm512_mask_mov_pd(w_val_vec, cond_mask, c_neg_times_dt_vec); + + // # 16 MULTs + __m512d x_term_vec = _mm512_mul_pd(f_alpha_beta_neg_x_vec, w_val_vec); + __m512d y_term_vec = _mm512_mul_pd(f_alpha_beta_neg_y_vec, w_val_vec); + + // # 16 ADDs + f_alpha_dt_x += _mm512_reduce_add_pd(x_term_vec); + f_alpha_dt_y += _mm512_reduce_add_pd(y_term_vec); + } + } + + // # ############################################################################################################################################################################################ + + for (; j < n_p; j++) { + + if (j == i) { + continue; + } + + // # 2 ADDs + double r_ab_x = p.curr_pos_x - pedestrians[j].curr_pos_x; + double r_ab_y = p.curr_pos_y - pedestrians[j].curr_pos_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_ab_norm = sqrt(r_ab_x * r_ab_x + r_ab_y * r_ab_y); + + // # 2 ADDs + double r_ab2_x = r_ab_x - pedestrians[j].s_b_e_x; + double r_ab2_y = r_ab_y - pedestrians[j].s_b_e_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_ab2_norm = sqrt(r_ab2_x * r_ab2_x + r_ab2_y * r_ab2_y); + + // # 1 ADD + double r_ab_norm_sum = r_ab_norm + r_ab2_norm; + + // # 1 MULT, 1 ADD + double two_b_sq = r_ab_norm_sum * r_ab_norm_sum - pedestrians[j].s_b_sq; + + // # 1 SQRT + double two_b = sqrt(two_b_sq); + + // # 5 MULTs, 1 DIV, 1 EXP + double scalar_mult_common = (r_ab_norm_sum / (two_b * r_ab_norm * r_ab2_norm)) * (NEG_V0_AB_div_TWO_SIGMA * exp(two_b * NEG_TWO_SIGMA_INV)); + + // # 2 MULTs + double scalar_mult_r_ab = scalar_mult_common * r_ab2_norm; + double scalar_mult_r_ab2 = scalar_mult_common * r_ab_norm; + + // # 4 MULTs, 2 ADDs + double f_alpha_beta_neg_x = r_ab_x * scalar_mult_r_ab + r_ab2_x * scalar_mult_r_ab2; + double f_alpha_beta_neg_y = r_ab_y * scalar_mult_r_ab + r_ab2_y * scalar_mult_r_ab2; + + double w_val; + + // # 3 MULTs, 1 ADD + double a = (p.e_x * f_alpha_beta_neg_x + p.e_y * f_alpha_beta_neg_y) * cos_phi_inv; + + // # 2 MULTs, 1 ADD + double b_sq = f_alpha_beta_neg_x * f_alpha_beta_neg_x + f_alpha_beta_neg_y * f_alpha_beta_neg_y; + + w_val = dt_neg; + // # 1 MULT + if (a >= 0 && (a * a > b_sq)) { + w_val = c_neg_times_dt; + } + + // # 2 MULTs, 2 ADDs + f_alpha_dt_x = f_alpha_dt_x + f_alpha_beta_neg_x * w_val; + f_alpha_dt_y = f_alpha_dt_y + f_alpha_beta_neg_y * w_val; + } + + // # ############################################################################################################################################################################################ + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + double v1_x = p.curr_pos_x - board.obstacles[k].start_x; + double v1_y = p.curr_pos_y - board.obstacles[k].start_y; + + // # 3 MULTs, 1 ADD + double projection = (v1_x * board.obstacles[k].obstacle_v_x + v1_y * board.obstacles[k].obstacle_v_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + // # 2 MULTs, 4 ADDs + double r_aB_x = p.curr_pos_x - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + double r_aB_y = p.curr_pos_y - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + + // # 2 MULTs, 1 EXP, 1 DIV + double scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + + // # 2 MULTs + double f_alpha_B_neg_x = r_aB_x * scalar_mult; + double f_alpha_B_neg_y = r_aB_y * scalar_mult; + + double w_val; + + // # 3 MULTs, 1 ADD + double a = (p.e_x * f_alpha_B_neg_x + p.e_y * f_alpha_B_neg_y) * cos_phi_inv; + + // # 2 MULTs, 1 ADD + double b_sq = f_alpha_B_neg_x * f_alpha_B_neg_x + f_alpha_B_neg_y * f_alpha_B_neg_y; + + w_val = dt_neg; + + // # 1 MULT + if (a >= 0 && (a * a > b_sq)) { + w_val = c_neg_times_dt; + } + + // # 2 MULTs + double f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + double f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + p.w_x += f_alpha_dt_x; + p.w_y += f_alpha_dt_y; + } + + // # ############################################################################################################################################################################################ + + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 1 SQRT, 2 MULTs, 1 ADD + double w_norm = sqrt(p.w_x * p.w_x + p.w_y * p.w_y); + + // # 1 DIV + double correction_factor = min(1.0, p.v_max / w_norm); + + // # 2 MULTs + p.curr_vel_x = p.w_x * correction_factor; + p.curr_vel_y = p.w_y * correction_factor; + + // # 2 MULTs, 2 ADDs + p.curr_pos_x = p.curr_pos_x + p.curr_vel_x * dt; + p.curr_pos_y = p.curr_pos_y + p.curr_vel_y * dt; + + if (p.color == 0 && p.curr_pos_x > BOARD_LENGTH_MINUS_ONE_POINT_FIVE) { + p.curr_pos_x = 1.0; + p.destination_y = p.curr_pos_y; + p.w_x = p.desired_v0; + p.w_y = 0.0; + p.curr_vel_x = p.w_x; + p.curr_vel_y = p.w_y; + } + if (p.color == 1 && p.curr_pos_x < 1.5) { + p.curr_pos_x = BOARD_LENGTH_MINUS_ONE; + p.destination_y = p.curr_pos_y; + p.w_x = -p.desired_v0; + p.w_y = 0.0; + p.curr_vel_x = p.w_x; + p.curr_vel_y = p.w_y; + } + + p.curr_pos_y = clamp(p.curr_pos_y, WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + // # 2 ADDs + double e_x = p.destination_x - p.curr_pos_x; + double e_y = p.destination_y - p.curr_pos_y; + + // # 1 DIV, 1 SQRT, 2 MULTs, 1 ADD + double e_norm_inv = 1.0 / sqrt(e_x * e_x + e_y * e_y); + + // # 2 MULTs + p.e_x = e_x * e_norm_inv; + p.e_y = e_y * e_norm_inv; + + // # 2 MULTs, 1 ADD + double velocity_norm_sq = p.curr_vel_x * p.curr_vel_x + p.curr_vel_y * p.curr_vel_y; + + // # 1 SQRT + double velocity_norm = sqrt(velocity_norm_sq); + + // # 5 MULTs + p.s_b_sq = velocity_norm_sq * delta_t_sq; + p.s_b_e_x = p.e_x * (velocity_norm * delta_t); + p.s_b_e_y = p.e_y * (velocity_norm * delta_t); + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, p.curr_pos_x, p.curr_pos_y, p.e_x, p.e_y, p.color); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} + +#endif diff --git a/variants/variant_baseline_flopcount.cpp b/variants/variant_baseline_flopcount.cpp new file mode 100644 index 0000000..6f4f90e --- /dev/null +++ b/variants/variant_baseline_flopcount.cpp @@ -0,0 +1,440 @@ +// This file is merged from the forces.cpp and social_forces_baseline.cpp +// The goal is that we from now on only have one file as our baseline +// This should make it more easy in the future to implement optimizations +// Our naming convention from now on is: variant_.cpp (Please make sure to keep that consistent, otherwise our Makefile wont work anymore) + +#include "../headers/board.hpp" +#include "../headers/constants.hpp" +#include "../headers/pedestrian.hpp" +#include "../headers/vector2d.hpp" + +#include +#include +#include +#include +#include // keep — forces code uses unqualified sqrt/exp +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0 +#define BOARD_LENGTH 50.0 +#define WALL_EPS 1e-3 +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999 + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +// forces.cpp + +// Flop count: 2 ADDs, 6 MULTs +double w_ped(Vector2d e, Vector2d f) { + double f_norm_sq = f.dot(f); + double rhs = f_norm_sq * cos_phi_sq; + double e_dot_f = e.dot(f); + double e_dot_f_sq = e_dot_f * e_dot_f; + if (e_dot_f >= 0.0 || e_dot_f_sq <= rhs) + return dt_neg; + else + return c_neg_times_dt; +} + +double w_obstacle(Vector2d e, Vector2d f) { + double e_dot_f = (f.y == 0) ? 0 : (f.y < 0 ? -e.y : e.y); + if (e_dot_f >= cos_phi) + return dt_neg; + else + return c_neg_times_dt; +} + +// Flop count: 2 ADDs, 4 MULTs +Vector2d acceleration_term_dt(const Pedestrian &alpha) { + + // # 2 MULTs + Vector2d desired_velocity = alpha.e * alpha.desired_v0; + + Vector2d actual_velocity = alpha.curr_vel; + + // # 2 ADDs, 2 MULTs + Vector2d f_alpha_0_dt = (desired_velocity - actual_velocity) * dt_times_tau_alpha_inv; + + return f_alpha_0_dt; +} + +// Flop count: 12 ADDs, 24 MULTs, 1 DIV, 3 SQRTs, 1 EXP +Vector2d pedestrian_repulsion_dt(const Pedestrian &alpha, const Pedestrian &beta) { + + // # 2 ADDs + // $\vec{r}_{\alpha\beta}$ + Vector2d r_ab = alpha.curr_pos - beta.curr_pos; + + // # 1 ADD, 2 MULTs, 1 SQRT + // $\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert$ + double r_ab_norm = r_ab.norm(); + r_ab_norm = r_ab_norm > EPS ? r_ab_norm : EPS; // Avoid division by zero + + // $v_\beta \Delta t \vec{e}_\beta$ + Vector2d s_b_e = beta.s_b_e; + + // # 2 ADDs + // $\vec{r}_{\alpha\beta} - \vec{v}_{\beta}\varDelta_{t}\vec{e}_{\beta}$ + Vector2d r_ab2 = r_ab - s_b_e; + + // # 1 ADD, 2 MULTs, 1 SQRT + // $\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert$ + double r_ab2_norm = r_ab2.norm(); + r_ab2_norm = r_ab2_norm > EPS ? r_ab2_norm : EPS; // Avoid division by zero + + // # 1 ADD + // $\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert$ + double r_ab_norm_sum = r_ab_norm + r_ab2_norm; + + // # 1 ADD, 1 MULTs, 1 SQRT + // + // $2b = \sqrt{(\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert)^2 - (v_\beta \Delta t)^2}$ + // + double two_b_sq = r_ab_norm_sum * r_ab_norm_sum - beta.s_b_sq; + two_b_sq = two_b_sq > EPS_SQ ? two_b_sq : EPS_SQ; // Avoid sqrt of negative and avoid division by zero + double two_b = sqrt(two_b_sq); + + // # 5 MULTs, 1 DIV, 1 EXP + // + // $\frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert\,\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}$ + // + double scalar_mult_common = (r_ab_norm_sum / (two_b * r_ab_norm * r_ab2_norm)) * (NEG_V0_AB_div_TWO_SIGMA * exp(two_b * NEG_TWO_SIGMA_INV)); + + // # 1 MULT + // + // $\frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert}$ + // + double scalar_mult_r_ab = scalar_mult_common * r_ab2_norm; + + // # 1 MULT + // + // $\frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}$ + // + double scalar_mult_r_ab2 = scalar_mult_common * r_ab_norm; + + // # 2 ADDs, 4 MULTs + // + // $\vec{-f}_{\alpha \beta}(\vec{r}_{\alpha \beta}) = \frac{-V^0_{\alpha \beta}}{2\sigma}e^{-b / \sigma} 2\grad_{\vec{r}_{\alpha \beta}}b $ + // + // + // $= \frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert}\,\vec{r}_{\alpha \beta} + \frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} - + // v_\beta \Delta t \vec{e}_\beta \Arrowvert}\,(\vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta)$ + // + // + // + // $2\grad_{\vec{r}_{\alpha \beta}}b = \frac{(\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert)(\frac{\vec{r}_{\alpha \beta}}{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert} + \frac{\vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta}{\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert})}{2b}$ + // + // + // $= \frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert}\,\vec{r}_{\alpha \beta} + \frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}\,(\vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta)$ + // + // + Vector2d f_alpha_beta_neg = r_ab * scalar_mult_r_ab + r_ab2 * scalar_mult_r_ab2; + + // # 2 ADDs, 8 MULTs + // + // $\vec{F}_{\alpha\beta}(\vec{e}_{\alpha}, \vec{r}_{\alpha \beta}).dt = w(\vec{e}_{\alpha}, -\vec{f}_{\alpha\beta}(\vec{r}_{\alpha \beta})).\vec{f}_{\alpha\beta}(\vec{r}_{\alpha \beta}).dt$ + // + Vector2d f_alpha_beta_dt = f_alpha_beta_neg * w_ped(alpha.e, f_alpha_beta_neg); + + return f_alpha_beta_dt; +} + +// Flop count: 8 ADDs, 13 MULTs, 1 DIV, 1 SQRT, 1 EXP +Vector2d obstacle_repulsion_dt(const Pedestrian &alpha, const Obstacle &B) { + + // # 7 ADDs, 5 MULTs + // $\vec{r}_{\alpha B}$ + Vector2d r_aB = alpha.curr_pos - B.find_nearest_obstacle_point(alpha.curr_pos); + + // # 1 ADD, 2 MULTs, 1 SQRT + // $\Arrowvert \vec{r}_{\alpha B} \Arrowvert$ + double r_aB_norm = r_aB.norm(); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; // Avoid division by zero + + // # 2 MULTs, 1 DIV, 1 EXP + // + // $\frac{-U^0_{\alpha B}}{R} e^{- \Arrowvert \vec{r}_{\alpha B} \Arrowvert / R}$ + // + double scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + + // # 2 MULTs + // + // $-\vec{F}_{\alpha B}(\vec{r}_{\alpha B}) = \frac{-U^0_{\alpha B}}{R} e^{- \Arrowvert \vec{r}_{\alpha B} \Arrowvert / R} \frac{\vec{r}_{\alpha B}}{\Arrowvert \vec{r}_{\alpha B} \Arrowvert}$ + // + Vector2d f_alpha_B_neg = r_aB * scalar_mult; + + // # 2 MULTs + // + // $\vec{F}_{\alpha B}(\vec{e}_{\alpha}, \vec{r}_{\alpha B}).dt = w(\vec{e}_{\alpha}, -\vec{F}_{\alpha B}(\vec{r}_{\alpha B})).\vec{F}_{\alpha B}(\vec{r}_{\alpha B}).dt$ + // + Vector2d f_alpha_B_dt = f_alpha_B_neg * w_obstacle(alpha.e, f_alpha_B_neg); + + return f_alpha_B_dt; +} + +// social_force_baseline.cpp + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; // Platform-provided random seed source. + mt19937 gen(rd()); // Non-reproducible initialization. +#else + mt19937 gen(SEED); // Reproducible initialization. +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + Pedestrian *P = new Pedestrian[n_p]; + + int n_p_half = n_p / 2; + + // Group of pedestrians walking from left to right. + for (int i = 0; i < n_p_half; i++) { + double x = x_gen_left(gen); + double y = y_gen(gen); + + Vector2d start_pos = Vector2d(x, y); + Vector2d destination = Vector2d(BOARD_LENGTH + 30.0, y); + + Vector2d init_e = destination - start_pos; + double init_e_norm = init_e.norm(); + Vector2d init_e_unit = init_e / init_e_norm; + + // Reject near-zero desired speeds to avoid pedestrians that barely move, + // and reject negative speeds because they would reverse the intended + // walking direction. + double desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + double v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(WHITE, Vector2d(), start_pos, init_e_unit, v_max, desired_v0, destination); + } + + // Group of pedestrians walking from right to left. + for (int i = n_p_half; i < n_p; i++) { + double x = x_gen_right(gen); + double y = y_gen(gen); + + Vector2d start_pos = Vector2d(x, y); + Vector2d destination = Vector2d(-30.0, y); + + Vector2d init_e = destination - start_pos; + double init_e_norm = init_e.norm(); + Vector2d init_e_unit = init_e / init_e_norm; + + // Reject near-zero desired speeds to avoid pedestrians that barely move, + // and reject negative speeds because they would reverse the intended + // walking direction. + double desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + double v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(BLACK, Vector2d(), start_pos, init_e_unit, v_max, desired_v0, destination); + } + + return P; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + // Avoid compiler unused parameter warning + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + // Each sample stores: time step, pedestrian id, x, y, e.x, e.y, color. + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + // Store the initial state before the first simulation step. + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + samples.emplace_back(0, i, p.curr_pos.x, p.curr_pos.y, p.e.x, p.e.y, p.color); + } + } +#endif + + // # ADDs: n_iter * ( + // # n_p * 4 + + // # n_p * (n_p - 1) * 14 + + // # n_p * board.n_obstacles * 10 + + // # n_p * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + // # n_p * (n_p - 1) * 24 + + // # n_p * board.n_obstacles * 13 + + // # n_p * 16 + // # ) + + // # DIVs: n_iter * ( + // # n_p * (n_p - 1) + + // # n_p * board.n_obstacles + + // # n_p * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * (n_p - 1) * 3 + + // # n_p * board.n_obstacles + + // # n_p * 3 + // # ) + + // # EXPs: n_iter * ( + // # n_p * (n_p - 1) + + // # n_p * board.n_obstacles + // # ) + + for (int t = 0; t < n_iter; t++) { + // Pass 1: Compute all forces from the current state. + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 2 ADDs, 4 MULTs + // + // $\vec{F}_\alpha(\vec{v}_\alpha, v^0_\alpha \vec{e}_\alpha) = \frac{1}{\tau_\alpha}(v^0_\alpha \vec{e}_\alpha - \vec{v}_\alpha)$ + // + Vector2d f_alpha_dt = acceleration_term_dt(p); + + // # (N-1) * (14 ADDs, 24 MULTs, 1 DIV, 3 SQRTs, 1 EXP) + // + // $\sum_{\beta} \vec{F}_{\alpha\beta}(\vec{e}_{\alpha},\vec{r}_{\alpha} - \vec{r}_{\beta})$ + // + for (int j = 0; j < n_p; j++) { + if (i == j) + continue; + + f_alpha_dt += pedestrian_repulsion_dt(p, pedestrians[j]); + } + + // # board.n_obstacles * (10 ADDs, 13 MULTs, 1 DIV, 1 SQRT, 1 EXP) + // + // $\sum_{B} \vec{F}_{\alpha B}(\vec{e}_{\alpha}, \vec{r}_{\alpha} - \vec{r}_{B})$ + // + for (int k = 0; k < board.n_obstacles; k++) { + f_alpha_dt += obstacle_repulsion_dt(p, board.obstacles[k]); + } + + // # 2 ADDs + // + // + // $\frac{d\vec{w}_\alpha}{dt} = \vec{F}_{\alpha}(t)$ + // + p.w += f_alpha_dt; + } + + // Pass 2: Update pedestrian states after all forces have been computed. + // # (7 ADDs, 16 MULTs, 2 DIVs, 3 SQRTs) * n_p + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 1 ADD, 2 MULTs, 1 SQRT + double w_norm = p.w.norm(); + + double w_norm2 = w_norm > EPS ? w_norm : EPS; // Avoid division by zero. + + // # 1 DIV + double correction_factor = std::min(1.0, p.v_max / w_norm2); + + // # 2 MULTs + p.curr_vel = p.w * correction_factor; + + // # 2 ADDs, 2 MULTs + // + // $\vec{r}_i^{t+1} = \vec{r}_i^t + \vec{v}_i^t dt$ + // + p.curr_pos = p.curr_pos + p.curr_vel * dt; + + // When a pedestrian reaches the end of the corridor, teleport them back + // to the opposite entrance while keeping the same y-coordinate. This + // maintains a constant pedestrian flow and makes lane formation easier to + // observe. + if (p.color == WHITE && p.curr_pos.x > (BOARD_LENGTH - 1.5)) { + p.curr_pos.x = 1.0; + p.destination.y = p.curr_pos.y; + p.w = Vector2d(p.desired_v0, 0.0); + p.curr_vel = p.w; + } + if (p.color == BLACK && p.curr_pos.x < 1.5) { + p.curr_pos.x = BOARD_LENGTH - 1.0; + p.destination.y = p.curr_pos.y; + p.w = Vector2d(-p.desired_v0, 0.0); + p.curr_vel = p.w; + } + + // Keep pedestrians inside the board boundaries. + p.curr_pos.y = clamp(p.curr_pos.y, WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + // # 2 ADDs + Vector2d e = p.destination - p.curr_pos; + + // # 1 ADD, 2 MULTs, 1 DIV, 1 SQRT + double e_norm = e.norm(); + double e_norm2 = e_norm > EPS ? e_norm : EPS; // Avoid division by zero. + double e_norm_inv = 1.0 / e_norm2; + + // # 2 MULTs + p.e = e * e_norm_inv; + + // # 1 ADD, 2 MULTs + double velocity_norm_sq = p.curr_vel.dot(p.curr_vel); + + // # 1 SQRT + double velocity_norm = std::sqrt(velocity_norm_sq); + + // # 1 MULT + p.s_b_sq = velocity_norm_sq * delta_t_sq; + + // # 3 MULTs + p.s_b_e = p.e * (velocity_norm * delta_t); + +#if !BENCHMARK + // Store the current pedestrian state for visualization. + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, p.curr_pos.x, p.curr_pos.y, p.e.x, p.e.y, p.color); + } +#endif + } + } + +#if !BENCHMARK + // Export recorded simulation states to CSV. + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} \ No newline at end of file diff --git a/variants/variant_float_baseline_flopcount.cpp b/variants/variant_float_baseline_flopcount.cpp new file mode 100644 index 0000000..820f769 --- /dev/null +++ b/variants/variant_float_baseline_flopcount.cpp @@ -0,0 +1,438 @@ +// # Changes: Added per-instruction flop count +// # Predecessor: variant_float_baseline.cpp + +#include "../headers/board_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_float.hpp" +#include "../headers/vector2d_float.hpp" + +#include +#include +#include +#include +#include // keep — forces code uses unqualified sqrt/exp +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +// forces.cpp + +// Flop count: 2 ADDs, 6 MULTs +float w_ped(Vector2d e, Vector2d f) { + float f_norm_sq = f.dot(f); + float rhs = f_norm_sq * cos_phi_sq; + float e_dot_f = e.dot(f); + float e_dot_f_sq = e_dot_f * e_dot_f; + if (e_dot_f >= 0.0 || e_dot_f_sq <= rhs) + return dt_neg; + else + return c_neg_times_dt; +} + +float w_obstacle(Vector2d e, Vector2d f) { + float e_dot_f = (f.y == 0) ? 0 : (f.y < 0 ? -e.y : e.y); + if (e_dot_f >= cos_phi) + return dt_neg; + else + return c_neg_times_dt; +} + +// Flop count: 2 ADDs, 4 MULTs +Vector2d acceleration_term_dt(const Pedestrian &alpha) { + + // # 2 MULTs + Vector2d desired_velocity = alpha.e * alpha.desired_v0; + + Vector2d actual_velocity = alpha.curr_vel; + + // # 2 ADDs, 2 MULTs + Vector2d f_alpha_0_dt = (desired_velocity - actual_velocity) * dt_times_tau_alpha_inv; + + return f_alpha_0_dt; +} + +// Flop count: 12 ADDs, 24 MULTs, 1 DIV, 3 SQRTs, 1 EXP +Vector2d pedestrian_repulsion_dt(const Pedestrian &alpha, const Pedestrian &beta) { + + // # 2 ADDs + // $\vec{r}_{\alpha\beta}$ + Vector2d r_ab = alpha.curr_pos - beta.curr_pos; + + // # 1 ADD, 2 MULTs, 1 SQRT + // $\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert$ + float r_ab_norm = r_ab.norm(); + r_ab_norm = r_ab_norm > EPS ? r_ab_norm : EPS; // Avoid division by zero + + // $v_\beta \Delta t \vec{e}_\beta$ + Vector2d s_b_e = beta.s_b_e; + + // # 2 ADDs + // $\vec{r}_{\alpha\beta} - \vec{v}_{\beta}\varDelta_{t}\vec{e}_{\beta}$ + Vector2d r_ab2 = r_ab - s_b_e; + + // # 1 ADD, 2 MULTs, 1 SQRT + // $\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert$ + float r_ab2_norm = r_ab2.norm(); + r_ab2_norm = r_ab2_norm > EPS ? r_ab2_norm : EPS; // Avoid division by zero + + // # 1 ADD + // $\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert$ + float r_ab_norm_sum = r_ab_norm + r_ab2_norm; + + // # 1 ADD, 1 MULTs, 1 SQRT + // + // $2b = \sqrt{(\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert)^2 - (v_\beta \Delta t)^2}$ + // + float two_b_sq = r_ab_norm_sum * r_ab_norm_sum - beta.s_b_sq; + two_b_sq = two_b_sq > EPS_SQ ? two_b_sq : EPS_SQ; // Avoid sqrt of negative and avoid division by zero + float two_b = sqrt(two_b_sq); + + // # 5 MULTs, 1 DIV, 1 EXP + // + // $\frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert\,\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}$ + // + float scalar_mult_common = (r_ab_norm_sum / (two_b * r_ab_norm * r_ab2_norm)) * (NEG_V0_AB_div_TWO_SIGMA * exp(two_b * NEG_TWO_SIGMA_INV)); + + // # 1 MULT + // + // $\frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert}$ + // + float scalar_mult_r_ab = scalar_mult_common * r_ab2_norm; + + // # 1 MULT + // + // $\frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}$ + // + float scalar_mult_r_ab2 = scalar_mult_common * r_ab_norm; + + // # 2 ADDs, 4 MULTs + // + // $\vec{-f}_{\alpha \beta}(\vec{r}_{\alpha \beta}) = \frac{-V^0_{\alpha \beta}}{2\sigma}e^{-b / \sigma} 2\grad_{\vec{r}_{\alpha \beta}}b $ + // + // + // $= \frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert}\,\vec{r}_{\alpha \beta} + \frac{-V^0_{\alpha\beta}}{2\sigma}\,e^{-b/\sigma}\,\frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} - + // v_\beta \Delta t \vec{e}_\beta \Arrowvert}\,(\vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta)$ + // + // + // + // $2\grad_{\vec{r}_{\alpha \beta}}b = \frac{(\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert)(\frac{\vec{r}_{\alpha \beta}}{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert} + \frac{\vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta}{\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert})}{2b}$ + // + // + // $= \frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert}\,\vec{r}_{\alpha \beta} + \frac{\Arrowvert \vec{r}_{\alpha \beta} \Arrowvert + \Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}{2b\,\Arrowvert \vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta \Arrowvert}\,(\vec{r}_{\alpha \beta} - v_\beta \Delta t \vec{e}_\beta)$ + // + // + Vector2d f_alpha_beta_neg = r_ab * scalar_mult_r_ab + r_ab2 * scalar_mult_r_ab2; + + // # 2 ADDs, 8 MULTs + // + // $\vec{F}_{\alpha\beta}(\vec{e}_{\alpha}, \vec{r}_{\alpha \beta}).dt = w(\vec{e}_{\alpha}, -\vec{f}_{\alpha\beta}(\vec{r}_{\alpha \beta})).\vec{f}_{\alpha\beta}(\vec{r}_{\alpha \beta}).dt$ + // + Vector2d f_alpha_beta_dt = f_alpha_beta_neg * w_ped(alpha.e, f_alpha_beta_neg); + + return f_alpha_beta_dt; +} + +// Flop count: 8 ADDs, 13 MULTs, 1 DIV, 1 SQRT, 1 EXP +Vector2d obstacle_repulsion_dt(const Pedestrian &alpha, const Obstacle &B) { + + // # 7 ADDs, 5 MULTs + // $\vec{r}_{\alpha B}$ + Vector2d r_aB = alpha.curr_pos - B.find_nearest_obstacle_point(alpha.curr_pos); + + // # 1 ADD, 2 MULTs, 1 SQRT + // $\Arrowvert \vec{r}_{\alpha B} \Arrowvert$ + float r_aB_norm = r_aB.norm(); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; // Avoid division by zero + + // # 2 MULTs, 1 DIV, 1 EXP + // + // $\frac{-U^0_{\alpha B}}{R} e^{- \Arrowvert \vec{r}_{\alpha B} \Arrowvert / R}$ + // + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + + // # 2 MULTs + // + // $-\vec{F}_{\alpha B}(\vec{r}_{\alpha B}) = \frac{-U^0_{\alpha B}}{R} e^{- \Arrowvert \vec{r}_{\alpha B} \Arrowvert / R} \frac{\vec{r}_{\alpha B}}{\Arrowvert \vec{r}_{\alpha B} \Arrowvert}$ + // + Vector2d f_alpha_B_neg = r_aB * scalar_mult; + + // # 2 MULTs + // + // $\vec{F}_{\alpha B}(\vec{e}_{\alpha}, \vec{r}_{\alpha B}).dt = w(\vec{e}_{\alpha}, -\vec{F}_{\alpha B}(\vec{r}_{\alpha B})).\vec{F}_{\alpha B}(\vec{r}_{\alpha B}).dt$ + // + Vector2d f_alpha_B_dt = f_alpha_B_neg * w_obstacle(alpha.e, f_alpha_B_neg); + + return f_alpha_B_dt; +} + +// social_force_baseline.cpp + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; // Platform-provided random seed source. + mt19937 gen(rd()); // Non-reproducible initialization. +#else + mt19937 gen(SEED); // Reproducible initialization. +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + Pedestrian *P = new Pedestrian[n_p]; + + int n_p_half = n_p / 2; + + // Group of pedestrians walking from left to right. + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + Vector2d start_pos = Vector2d(x, y); + Vector2d destination = Vector2d(BOARD_LENGTH + 30.0, y); + + Vector2d init_e = destination - start_pos; + float init_e_norm = init_e.norm(); + Vector2d init_e_unit = init_e / init_e_norm; + + // Reject near-zero desired speeds to avoid pedestrians that barely move, + // and reject negative speeds because they would reverse the intended + // walking direction. + float desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + float v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(WHITE, Vector2d(), start_pos, init_e_unit, v_max, desired_v0, destination); + } + + // Group of pedestrians walking from right to left. + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + Vector2d start_pos = Vector2d(x, y); + Vector2d destination = Vector2d(-30.0, y); + + Vector2d init_e = destination - start_pos; + float init_e_norm = init_e.norm(); + Vector2d init_e_unit = init_e / init_e_norm; + + // Reject near-zero desired speeds to avoid pedestrians that barely move, + // and reject negative speeds because they would reverse the intended + // walking direction. + float desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + float v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(BLACK, Vector2d(), start_pos, init_e_unit, v_max, desired_v0, destination); + } + + return P; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + // Avoid compiler unused parameter warning + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + // Each sample stores: time step, pedestrian id, x, y, e.x, e.y, color. + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + // Store the initial state before the first simulation step. + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + samples.emplace_back(0, i, p.curr_pos.x, p.curr_pos.y, p.e.x, p.e.y, p.color); + } + } +#endif + + // # ADDs: n_iter * ( + // # n_p * 4 + + // # n_p * (n_p - 1) * 14 + + // # n_p * board.n_obstacles * 10 + + // # n_p * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + // # n_p * (n_p - 1) * 24 + + // # n_p * board.n_obstacles * 13 + + // # n_p * 16 + // # ) + + // # DIVs: n_iter * ( + // # n_p * (n_p - 1) + + // # n_p * board.n_obstacles + + // # n_p * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * (n_p - 1) * 3 + + // # n_p * board.n_obstacles + + // # n_p * 3 + // # ) + + // # EXPs: n_iter * ( + // # n_p * (n_p - 1) + + // # n_p * board.n_obstacles + // # ) + + for (int t = 0; t < n_iter; t++) { + // Pass 1: Compute all forces from the current state. + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 2 ADDs, 4 MULTs + // + // $\vec{F}_\alpha(\vec{v}_\alpha, v^0_\alpha \vec{e}_\alpha) = \frac{1}{\tau_\alpha}(v^0_\alpha \vec{e}_\alpha - \vec{v}_\alpha)$ + // + Vector2d f_alpha_dt = acceleration_term_dt(p); + + // # (N-1) * (14 ADDs, 24 MULTs, 1 DIV, 3 SQRTs, 1 EXP) + // + // $\sum_{\beta} \vec{F}_{\alpha\beta}(\vec{e}_{\alpha},\vec{r}_{\alpha} - \vec{r}_{\beta})$ + // + for (int j = 0; j < n_p; j++) { + if (i == j) + continue; + + f_alpha_dt += pedestrian_repulsion_dt(p, pedestrians[j]); + } + + // # board.n_obstacles * (10 ADDs, 13 MULTs, 1 DIV, 1 SQRT, 1 EXP) + // + // $\sum_{B} \vec{F}_{\alpha B}(\vec{e}_{\alpha}, \vec{r}_{\alpha} - \vec{r}_{B})$ + // + for (int k = 0; k < board.n_obstacles; k++) { + f_alpha_dt += obstacle_repulsion_dt(p, board.obstacles[k]); + } + + // # 2 ADDs + // + // + // $\frac{d\vec{w}_\alpha}{dt} = \vec{F}_{\alpha}(t)$ + // + p.w += f_alpha_dt; + } + + // Pass 2: Update pedestrian states after all forces have been computed. + // # (7 ADDs, 16 MULTs, 2 DIVs, 3 SQRTs) * n_p + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 1 ADD, 2 MULTs, 1 SQRT + float w_norm = p.w.norm(); + + float w_norm2 = w_norm > EPS ? w_norm : EPS; // Avoid division by zero. + + // # 1 DIV + float correction_factor = std::min(1.0f, p.v_max / w_norm2); + + // # 2 MULTs + p.curr_vel = p.w * correction_factor; + + // # 2 ADDs, 2 MULTs + // + // $\vec{r}_i^{t+1} = \vec{r}_i^t + \vec{v}_i^t dt$ + // + p.curr_pos = p.curr_pos + p.curr_vel * dt; + + // When a pedestrian reaches the end of the corridor, teleport them back + // to the opposite entrance while keeping the same y-coordinate. This + // maintains a constant pedestrian flow and makes lane formation easier to + // observe. + if (p.color == WHITE && p.curr_pos.x > (BOARD_LENGTH - 1.5)) { + p.curr_pos.x = 1.0; + p.destination.y = p.curr_pos.y; + p.w = Vector2d(p.desired_v0, 0.0); + p.curr_vel = p.w; + } + if (p.color == BLACK && p.curr_pos.x < 1.5) { + p.curr_pos.x = BOARD_LENGTH - 1.0; + p.destination.y = p.curr_pos.y; + p.w = Vector2d(-p.desired_v0, 0.0); + p.curr_vel = p.w; + } + + // Keep pedestrians inside the board boundaries. + p.curr_pos.y = clamp(p.curr_pos.y, WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + // # 2 ADDs + Vector2d e = p.destination - p.curr_pos; + + // # 1 ADD, 2 MULTs, 1 DIV, 1 SQRT + float e_norm = e.norm(); + float e_norm2 = e_norm > EPS ? e_norm : EPS; // Avoid division by zero. + float e_norm_inv = 1.0 / e_norm2; + + // # 2 MULTs + p.e = e * e_norm_inv; + + // # 1 ADD, 2 MULTs + float velocity_norm_sq = p.curr_vel.dot(p.curr_vel); + + // # 1 SQRT + float velocity_norm = std::sqrt(velocity_norm_sq); + + // # 1 MULT + p.s_b_sq = velocity_norm_sq * delta_t_sq; + + // # 3 MULTs + p.s_b_e = p.e * (velocity_norm * delta_t); + +#if !BENCHMARK + // Store the current pedestrian state for visualization. + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, p.curr_pos.x, p.curr_pos.y, p.e.x, p.e.y, p.color); + } +#endif + } + } + +#if !BENCHMARK + // Export recorded simulation states to CSV. + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} \ No newline at end of file diff --git a/variants/variant_float_inlining_SoA_AVX2_polyexp_expfix.cpp b/variants/variant_float_inlining_SoA_AVX2_polyexp_expfix.cpp index 2443933..572a2bc 100644 --- a/variants/variant_float_inlining_SoA_AVX2_polyexp_expfix.cpp +++ b/variants/variant_float_inlining_SoA_AVX2_polyexp_expfix.cpp @@ -180,6 +180,7 @@ static inline __m256 exp256_ps(__m256 x) { const __m256 ln2 = _mm256_set1_ps(0.6931471805599453f); __m256 r = _mm256_fnmadd_ps(nf, ln2, x); // # 8 MULTs, 8 ADDs + const __m256 c13 = _mm256_set1_ps(c13_scalar); const __m256 c12 = _mm256_set1_ps(c12_scalar); const __m256 c11 = _mm256_set1_ps(c11_scalar); const __m256 c10 = _mm256_set1_ps(c10_scalar); @@ -194,7 +195,7 @@ static inline __m256 exp256_ps(__m256 x) { const __m256 c1 = _mm256_set1_ps(c1_scalar); const __m256 c0 = _mm256_set1_ps(c0_scalar); - __m256 p = c12; + __m256 p = c13; // # 13 * (8 MULTs, 8 ADDs) // # = 104 MULTs, 104 ADDs diff --git a/variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix.cpp b/variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix.cpp index 9c05350..0de7907 100644 --- a/variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix.cpp +++ b/variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_expfix.cpp @@ -197,6 +197,7 @@ static inline __m256 exp256_ps(__m256 x) { const __m256 ln2 = _mm256_set1_ps(0.6931471805599453f); __m256 r = _mm256_fnmadd_ps(nf, ln2, x); // # 8 MULTs, 8 ADDs + const __m256 c13 = _mm256_set1_ps(c13_scalar); const __m256 c12 = _mm256_set1_ps(c12_scalar); const __m256 c11 = _mm256_set1_ps(c11_scalar); const __m256 c10 = _mm256_set1_ps(c10_scalar); @@ -211,7 +212,7 @@ static inline __m256 exp256_ps(__m256 x) { const __m256 c1 = _mm256_set1_ps(c1_scalar); const __m256 c0 = _mm256_set1_ps(c0_scalar); - __m256 p = c12; + __m256 p = c13; // # 13 * (8 MULTs, 8 ADDs) // # = 104 MULTs, 104 ADDs diff --git a/variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix.cpp b/variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix.cpp index c973f98..e6760fb 100644 --- a/variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix.cpp +++ b/variants/variant_float_inlining_SoA_AVX2_polyexp_rsqrt_loopopt_expfix.cpp @@ -197,6 +197,7 @@ static inline __m256 exp256_ps(__m256 x) { const __m256 ln2 = _mm256_set1_ps(0.6931471805599453f); __m256 r = _mm256_fnmadd_ps(nf, ln2, x); // # 8 MULTs, 8 ADDs + const __m256 c13 = _mm256_set1_ps(c13_scalar); const __m256 c12 = _mm256_set1_ps(c12_scalar); const __m256 c11 = _mm256_set1_ps(c11_scalar); const __m256 c10 = _mm256_set1_ps(c10_scalar); @@ -211,7 +212,7 @@ static inline __m256 exp256_ps(__m256 x) { const __m256 c1 = _mm256_set1_ps(c1_scalar); const __m256 c0 = _mm256_set1_ps(c0_scalar); - __m256 p = c12; + __m256 p = c13; // # 13 * (8 MULTs, 8 ADDs) // # = 104 MULTs, 104 ADDs diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_expfix.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_expfix.cpp new file mode 100644 index 0000000..bcbeeea --- /dev/null +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_expfix.cpp @@ -0,0 +1,540 @@ +// # Changes: Ported AVX2 to AVX512 +// # Predecessor: variant_float_inlining_SoA_AVX2_polyexp.cpp + +#include "../headers/board_reduced_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_reduced_float.hpp" + +#include + +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0f +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 15) & ~15; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + float dest_x = BOARD_LENGTH + 30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + float dest_x = -30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9f; + pos_y[j] = 1e9f; + sb_sq[j] = 0.0f; + sb_e_x[j] = 0.0f; + sb_e_y[j] = 0.0f; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 256 MULTs, 224 ADDs +static inline __m512 _avx512_exp_ps(__m512 x) { + + const __m512 log2e = _mm512_set1_ps(1.4426950408889634f); + + // # 16 MULTs + __m512 nf = _mm512_roundscale_ps(_mm512_mul_ps(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + + const __m512 ln2 = _mm512_set1_ps(0.6931471805599453f); + + // # 16 MULTs, 16 ADDs + __m512 r = _mm512_fnmadd_ps(nf, ln2, x); + + const __m512 c13 = _mm512_set1_ps(c13_scalar); + const __m512 c12 = _mm512_set1_ps(c12_scalar); + const __m512 c11 = _mm512_set1_ps(c11_scalar); + const __m512 c10 = _mm512_set1_ps(c10_scalar); + const __m512 c9 = _mm512_set1_ps(c9_scalar); + const __m512 c8 = _mm512_set1_ps(c8_scalar); + const __m512 c7 = _mm512_set1_ps(c7_scalar); + const __m512 c6 = _mm512_set1_ps(c6_scalar); + const __m512 c5 = _mm512_set1_ps(c5_scalar); + const __m512 c4 = _mm512_set1_ps(c4_scalar); + const __m512 c3 = _mm512_set1_ps(c3_scalar); + const __m512 c2 = _mm512_set1_ps(c2_scalar); + const __m512 c1 = _mm512_set1_ps(c1_scalar); + const __m512 c0 = _mm512_set1_ps(c0_scalar); + + __m512 p = c13; + + // # 13 * (16 MULTs, 16 ADDs) + // # = 208 MULTs, 208 ADDs + p = _mm512_fmadd_ps(p, r, c12); + p = _mm512_fmadd_ps(p, r, c11); + p = _mm512_fmadd_ps(p, r, c10); + p = _mm512_fmadd_ps(p, r, c9); + p = _mm512_fmadd_ps(p, r, c8); + p = _mm512_fmadd_ps(p, r, c7); + p = _mm512_fmadd_ps(p, r, c6); + p = _mm512_fmadd_ps(p, r, c5); + p = _mm512_fmadd_ps(p, r, c4); + p = _mm512_fmadd_ps(p, r, c3); + p = _mm512_fmadd_ps(p, r, c2); + p = _mm512_fmadd_ps(p, r, c1); + p = _mm512_fmadd_ps(p, r, c0); + + __m512i ni = _mm512_cvtps_epi32(nf); + __m512i biased = _mm512_add_epi32(ni, _mm512_set1_epi32(127)); + __m512i scaled = _mm512_slli_epi32(biased, 23); + __m512 pow2n = _mm512_castsi512_ps(scaled); + + // # 16 MULTs + return _mm512_mul_ps(p, pow2n); +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + (void)pedestrians; +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 15) & ~15; + + alignas(64) const float lane_offset_arr[16] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f}; + const __m512 lane_off = _mm512_load_ps(lane_offset_arr); + + const __m512 v_neg_v0_div_2s = _mm512_set1_ps(NEG_V0_AB_div_TWO_SIGMA); + const __m512 v_neg_2s_inv = _mm512_set1_ps(NEG_TWO_SIGMA_INV); + const __m512 v_cos_phi_sq = _mm512_set1_ps(cos_phi_sq); + const __m512 v_dt_neg = _mm512_set1_ps(dt_neg); + const __m512 v_c_neg_dt = _mm512_set1_ps(c_neg_times_dt); + const __m512 v_zero = _mm512_setzero_ps(); + const __m512 v_one = _mm512_set1_ps(1.0f); + const __m512 v_eps = _mm512_set1_ps(EPS); + const __m512 v_eps_sq = _mm512_set1_ps(EPS_SQ); + const __m512 v_np = _mm512_set1_ps((float)n_p); + const __m512 v_exp_min = _mm512_set1_ps(-87.0f); + + // # ADDs: n_iter * ( + // # n_p * 36 + + // # n_p * n_p_pad * 29 + + // # n_p * board.n_obstacles * 10 + + // # n_p * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + + // # n_p * n_p_pad * 40 + + // # n_p * board.n_obstacles * 13 + + // # n_p * 17 + // # ) + + // # DIVs: n_iter * ( + // # n_p * n_p_pad + + // # n_p * board.n_obstacles + + // # n_p * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * n_p_pad * 3 + + // # n_p * board.n_obstacles + + // # n_p * 3 + // # ) + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + + // # 2 MULTs + float desired_velocity_x = e_x[i] * desired_v0[i]; + float desired_velocity_y = e_y[i] * desired_v0[i]; + + // # 2 ADDs, 2 MULTs + float f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; + float f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; + + const __m512 pix = _mm512_set1_ps(pos_x[i]); + const __m512 piy = _mm512_set1_ps(pos_y[i]); + const __m512 eix = _mm512_set1_ps(e_x[i]); + const __m512 eiy = _mm512_set1_ps(e_y[i]); + const __m512 v_i = _mm512_set1_ps((float)i); + + __m512 acc_x = _mm512_setzero_ps(); + __m512 acc_y = _mm512_setzero_ps(); + + for (int j = 0; j < n_p_pad; j += 16) { + + // # 16 ADDs + __m512 j_idx = _mm512_add_ps(_mm512_set1_ps((float)j), lane_off); + + __mmask16 m_neq_i = _mm512_cmp_ps_mask(j_idx, v_i, _CMP_NEQ_OQ); + __mmask16 m_in_range = _mm512_cmp_ps_mask(j_idx, v_np, _CMP_LT_OQ); + __mmask16 active = m_neq_i & m_in_range; + + __m512 pjx = _mm512_loadu_ps(&pos_x[j]); + __m512 pjy = _mm512_loadu_ps(&pos_y[j]); + __m512 sbe_jx = _mm512_loadu_ps(&sb_e_x[j]); + __m512 sbe_jy = _mm512_loadu_ps(&sb_e_y[j]); + __m512 sb_jsq = _mm512_loadu_ps(&sb_sq[j]); + + // # 32 ADDs + __m512 r_ab_x = _mm512_sub_ps(pix, pjx); + __m512 r_ab_y = _mm512_sub_ps(piy, pjy); + + // # 32 MULTs, 16 ADDs + __m512 r_ab_n2 = _mm512_fmadd_ps(r_ab_x, r_ab_x, _mm512_mul_ps(r_ab_y, r_ab_y)); + + // # 16 SQRTs + __m512 r_ab_n = _mm512_sqrt_ps(r_ab_n2); + + r_ab_n = _mm512_max_ps(r_ab_n, v_eps); + + // # 32 ADDs + __m512 r_ab2_x = _mm512_sub_ps(r_ab_x, sbe_jx); + __m512 r_ab2_y = _mm512_sub_ps(r_ab_y, sbe_jy); + + // # 32 MULTs, 16 ADDs + __m512 r_ab2_n2 = _mm512_fmadd_ps(r_ab2_x, r_ab2_x, _mm512_mul_ps(r_ab2_y, r_ab2_y)); + + // # 16 SQRTs + __m512 r_ab2_n = _mm512_sqrt_ps(r_ab2_n2); + + r_ab2_n = _mm512_max_ps(r_ab2_n, v_eps); + + // # 16 ADDs + __m512 r_sum = _mm512_add_ps(r_ab_n, r_ab2_n); + + // # 16 MULTs, 16 ADDs + __m512 two_b_sq = _mm512_fmsub_ps(r_sum, r_sum, sb_jsq); + + two_b_sq = _mm512_max_ps(two_b_sq, v_eps_sq); + + // # 16 SQRTs + __m512 two_b = _mm512_sqrt_ps(two_b_sq); + + // # 16 MULTs + __m512 e_arg = _mm512_mul_ps(two_b, v_neg_2s_inv); + + e_arg = _mm512_max_ps(e_arg, v_exp_min); + + // # 256 MULTs, 224 ADDs + __m512 e_val = _avx512_exp_ps(e_arg); + + // # 64 MULTs + __m512 numer = _mm512_mul_ps(_mm512_mul_ps(r_sum, v_neg_v0_div_2s), e_val); + __m512 denom = _mm512_mul_ps(_mm512_mul_ps(two_b, r_ab_n), r_ab2_n); + + __m512 denom_safe = _mm512_mask_blend_ps(active, v_one, denom); + + // # 16 DIVs + __m512 smc = _mm512_div_ps(numer, denom_safe); + + // # 32 MULTs + __m512 sm_r_ab = _mm512_mul_ps(smc, r_ab2_n); + __m512 sm_r_ab2 = _mm512_mul_ps(smc, r_ab_n); + + // # 64 MULTs, 32 ADDs + __m512 f_x = _mm512_fmadd_ps(r_ab2_x, sm_r_ab2, _mm512_mul_ps(r_ab_x, sm_r_ab)); + __m512 f_y = _mm512_fmadd_ps(r_ab2_y, sm_r_ab2, _mm512_mul_ps(r_ab_y, sm_r_ab)); + + // # 32 MULTs, 16 ADDs + __m512 f_norm_sq = _mm512_fmadd_ps(f_x, f_x, _mm512_mul_ps(f_y, f_y)); + + // # 16 MULTs + __m512 rhs = _mm512_mul_ps(f_norm_sq, v_cos_phi_sq); + + // # 32 MULTs, 16 ADDs + __m512 e_dot_f = _mm512_fmadd_ps(eix, f_x, _mm512_mul_ps(eiy, f_y)); + + // # 16 MULTs + __m512 e_dot_f_sq = _mm512_mul_ps(e_dot_f, e_dot_f); + + __mmask16 c1 = _mm512_cmp_ps_mask(e_dot_f, v_zero, _CMP_LT_OQ); + __mmask16 c2 = _mm512_cmp_ps_mask(e_dot_f_sq, rhs, _CMP_GT_OQ); + __mmask16 cond = c1 & c2; + + __m512 w_val = _mm512_mask_blend_ps(cond, v_dt_neg, v_c_neg_dt); + + __m512 f_x_safe = _mm512_maskz_mov_ps(active, f_x); + __m512 f_y_safe = _mm512_maskz_mov_ps(active, f_y); + + // # 32 MULTs, 32 ADDs + acc_x = _mm512_fmadd_ps(f_x_safe, w_val, acc_x); + acc_y = _mm512_fmadd_ps(f_y_safe, w_val, acc_y); + } + + // # 32 ADDs + f_alpha_dt_x += _mm512_reduce_add_ps(acc_x); + f_alpha_dt_y += _mm512_reduce_add_ps(acc_y); + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + float v1_x = pos_x[i] - board.obstacles[k].start_x; + float v1_y = pos_y[i] - board.obstacles[k].start_y; + float v2_x = board.obstacles[k].obstacle_v_x; + float v2_y = board.obstacles[k].obstacle_v_y; + + // # 3 MULTs, 1 ADD + float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0f) + projection = 0.0f; + else if (projection > 1.0f) + projection = 1.0f; + + // # 4 ADDs, 2 MULTs + float r_aB_x = pos_x[i] - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + float r_aB_y = pos_y[i] - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; + + // # 4 MULTs, 1 EXP, 1 DIV + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + float f_alpha_B_neg_x = r_aB_x * scalar_mult; + float f_alpha_B_neg_y = r_aB_y * scalar_mult; + + float w_val = dt_neg; + float e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y[i] : e_y[i]); + + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTS + float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p; i++) { + + // # 1 SQRT, 2 MULTs, 1 ADD + float w_norm = sqrt(w_x[i] * w_x[i] + w_y[i] * w_y[i]); + + float w_norm2 = w_norm > EPS ? w_norm : EPS; + + // # 1 DIV + float correction_factor = min(1.0f, v_max[i] / w_norm2); + + // # 2 MULTs + curr_vel_x[i] = w_x[i] * correction_factor; + curr_vel_y[i] = w_y[i] * correction_factor; + + // # 2 MULTs, 2 ADDs + pos_x[i] = pos_x[i] + curr_vel_x[i] * dt; + pos_y[i] = pos_y[i] + curr_vel_y[i] * dt; + + if (color[i] == 0 && pos_x[i] > BOARD_LENGTH_MINUS_ONE_POINT_FIVE) { + pos_x[i] = 1.0f; + destination_y[i] = pos_y[i]; + w_x[i] = desired_v0[i]; + w_y[i] = 0.0f; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + if (color[i] == 1 && pos_x[i] < 1.5f) { + pos_x[i] = BOARD_LENGTH_MINUS_ONE; + destination_y[i] = pos_y[i]; + w_x[i] = -desired_v0[i]; + w_y[i] = 0.0f; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + + pos_y[i] = clamp(pos_y[i], WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + // # 2 ADDs + float ex = destination_x[i] - pos_x[i]; + float ey = destination_y[i] - pos_y[i]; + + // # 1 SQRT, 2 MULTs, 1 ADD + float e_norm = sqrt(ex * ex + ey * ey); + + float e_norm2 = e_norm > EPS ? e_norm : EPS; + + // # 1 DIV + float e_norm_inv = 1.0f / e_norm2; + + // # 2 MULTs + e_x[i] = ex * e_norm_inv; + e_y[i] = ey * e_norm_inv; + + // # 2 MULTs, 1 ADD + float velocity_norm_sq = curr_vel_x[i] * curr_vel_x[i] + curr_vel_y[i] * curr_vel_y[i]; + + // # 1 SQRT + float velocity_norm = sqrt(velocity_norm_sq); + + // # 5 MULTs + sb_sq[i] = velocity_norm_sq * delta_t_sq; + sb_e_x[i] = e_x[i] * (velocity_norm * delta_t); + sb_e_y[i] = e_y[i] * (velocity_norm * delta_t); + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp new file mode 100644 index 0000000..f0ab633 --- /dev/null +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp @@ -0,0 +1,557 @@ +// # Changes: Added more correction rounds to _avx512_exp_ps to do 30 flops per scalar +// # Predecessor: variant_float_inlining_SoA_AVX512_polyexp_fastinvsqrt.cpp + +#include "../headers/board_reduced_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_reduced_float.hpp" + +#include + +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0f +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 15) & ~15; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + float dest_x = BOARD_LENGTH + 30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + float dest_x = -30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9f; + pos_y[j] = 1e9f; + sb_sq[j] = 0.0f; + sb_e_x[j] = 0.0f; + sb_e_y[j] = 0.0f; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 256 MULTs, 224 ADDs +static inline __m512 _avx512_exp_ps(__m512 x) { + + const __m512 log2e = _mm512_set1_ps(1.4426950408889634f); + + // # 16 MULTs + __m512 nf = _mm512_roundscale_ps(_mm512_mul_ps(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + + const __m512 ln2 = _mm512_set1_ps(0.6931471805599453f); + + // # 16 MULTs, 16 ADDs + __m512 r = _mm512_fnmadd_ps(nf, ln2, x); + + const __m512 c13 = _mm512_set1_ps(c13_scalar); + const __m512 c12 = _mm512_set1_ps(c12_scalar); + const __m512 c11 = _mm512_set1_ps(c11_scalar); + const __m512 c10 = _mm512_set1_ps(c10_scalar); + const __m512 c9 = _mm512_set1_ps(c9_scalar); + const __m512 c8 = _mm512_set1_ps(c8_scalar); + const __m512 c7 = _mm512_set1_ps(c7_scalar); + const __m512 c6 = _mm512_set1_ps(c6_scalar); + const __m512 c5 = _mm512_set1_ps(c5_scalar); + const __m512 c4 = _mm512_set1_ps(c4_scalar); + const __m512 c3 = _mm512_set1_ps(c3_scalar); + const __m512 c2 = _mm512_set1_ps(c2_scalar); + const __m512 c1 = _mm512_set1_ps(c1_scalar); + const __m512 c0 = _mm512_set1_ps(c0_scalar); + + __m512 p = c13; + + // # 13 * (16 MULTs, 16 ADDs) + // # = 208 MULTs, 208 ADDs + p = _mm512_fmadd_ps(p, r, c12); + p = _mm512_fmadd_ps(p, r, c11); + p = _mm512_fmadd_ps(p, r, c10); + p = _mm512_fmadd_ps(p, r, c9); + p = _mm512_fmadd_ps(p, r, c8); + p = _mm512_fmadd_ps(p, r, c7); + p = _mm512_fmadd_ps(p, r, c6); + p = _mm512_fmadd_ps(p, r, c5); + p = _mm512_fmadd_ps(p, r, c4); + p = _mm512_fmadd_ps(p, r, c3); + p = _mm512_fmadd_ps(p, r, c2); + p = _mm512_fmadd_ps(p, r, c1); + p = _mm512_fmadd_ps(p, r, c0); + + __m512i ni = _mm512_cvtps_epi32(nf); + __m512i biased = _mm512_add_epi32(ni, _mm512_set1_epi32(127)); + __m512i scaled = _mm512_slli_epi32(biased, 23); + __m512 pow2n = _mm512_castsi512_ps(scaled); + + // # 16 MULTs + return _mm512_mul_ps(p, pow2n); +} + +// # 7 MULTs, 2 ADDs +static inline float fast_inv_sqrt(float number) { + float y = number; + + uint32_t i = bit_cast(y); + + i = 0x5f3759df - (i >> 1); + + y = bit_cast(i); + + // # 1 MULT + float x2 = number * 0.5; + + // # 6 MULTs, 2 ADDs + y = y * (1.5 - (x2 * y * y)); + y = y * (1.5 - (x2 * y * y)); + + return y; +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + (void)pedestrians; +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 15) & ~15; + + alignas(64) const float lane_offset_arr[16] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f}; + const __m512 lane_off = _mm512_load_ps(lane_offset_arr); + + const __m512 v_neg_v0_div_2s = _mm512_set1_ps(NEG_V0_AB_div_TWO_SIGMA); + const __m512 v_neg_2s_inv = _mm512_set1_ps(NEG_TWO_SIGMA_INV); + const __m512 v_cos_phi_sq = _mm512_set1_ps(cos_phi_sq); + const __m512 v_dt_neg = _mm512_set1_ps(dt_neg); + const __m512 v_c_neg_dt = _mm512_set1_ps(c_neg_times_dt); + const __m512 v_zero = _mm512_setzero_ps(); + const __m512 v_one = _mm512_set1_ps(1.0f); + const __m512 v_eps = _mm512_set1_ps(EPS); + const __m512 v_eps_sq = _mm512_set1_ps(EPS_SQ); + const __m512 v_np = _mm512_set1_ps((float)n_p); + const __m512 v_exp_min = _mm512_set1_ps(-87.0f); + + // # ADDs: n_iter * ( + // # n_p * 36 + + // # n_p * n_p_pad * 29 + + // # n_p * board.n_obstacles * 10 + + // # n_p * 11 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + + // # n_p * n_p_pad * 40 + + // # n_p * board.n_obstacles * 13 + + // # n_p * 30 + // # ) + + // # DIVs: n_iter * ( + // # n_p * n_p_pad + + // # n_p * board.n_obstacles + // # ) + + // # SQRTs: n_iter * ( + // # n_p * n_p_pad * 3 + + // # n_p * board.n_obstacles + + // # n_p + // # ) + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + + // # 2 MULTs + float desired_velocity_x = e_x[i] * desired_v0[i]; + float desired_velocity_y = e_y[i] * desired_v0[i]; + + // # 2 ADDs, 2 MULTs + float f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; + float f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; + + const __m512 pix = _mm512_set1_ps(pos_x[i]); + const __m512 piy = _mm512_set1_ps(pos_y[i]); + const __m512 eix = _mm512_set1_ps(e_x[i]); + const __m512 eiy = _mm512_set1_ps(e_y[i]); + const __m512 v_i = _mm512_set1_ps((float)i); + + __m512 acc_x = _mm512_setzero_ps(); + __m512 acc_y = _mm512_setzero_ps(); + + for (int j = 0; j < n_p_pad; j += 16) { + + // # 16 ADDs + __m512 j_idx = _mm512_add_ps(_mm512_set1_ps((float)j), lane_off); + + __mmask16 m_neq_i = _mm512_cmp_ps_mask(j_idx, v_i, _CMP_NEQ_OQ); + __mmask16 m_in_range = _mm512_cmp_ps_mask(j_idx, v_np, _CMP_LT_OQ); + __mmask16 active = m_neq_i & m_in_range; + + __m512 pjx = _mm512_loadu_ps(&pos_x[j]); + __m512 pjy = _mm512_loadu_ps(&pos_y[j]); + __m512 sbe_jx = _mm512_loadu_ps(&sb_e_x[j]); + __m512 sbe_jy = _mm512_loadu_ps(&sb_e_y[j]); + __m512 sb_jsq = _mm512_loadu_ps(&sb_sq[j]); + + // # 32 ADDs + __m512 r_ab_x = _mm512_sub_ps(pix, pjx); + __m512 r_ab_y = _mm512_sub_ps(piy, pjy); + + // # 32 MULTs, 16 ADDs + __m512 r_ab_n2 = _mm512_fmadd_ps(r_ab_x, r_ab_x, _mm512_mul_ps(r_ab_y, r_ab_y)); + + // # 16 SQRTs + __m512 r_ab_n = _mm512_sqrt_ps(r_ab_n2); + + r_ab_n = _mm512_max_ps(r_ab_n, v_eps); + + // # 32 ADDs + __m512 r_ab2_x = _mm512_sub_ps(r_ab_x, sbe_jx); + __m512 r_ab2_y = _mm512_sub_ps(r_ab_y, sbe_jy); + + // # 32 MULTs, 16 ADDs + __m512 r_ab2_n2 = _mm512_fmadd_ps(r_ab2_x, r_ab2_x, _mm512_mul_ps(r_ab2_y, r_ab2_y)); + + // # 16 SQRTs + __m512 r_ab2_n = _mm512_sqrt_ps(r_ab2_n2); + + r_ab2_n = _mm512_max_ps(r_ab2_n, v_eps); + + // # 16 ADDs + __m512 r_sum = _mm512_add_ps(r_ab_n, r_ab2_n); + + // # 16 MULTs, 16 ADDs + __m512 two_b_sq = _mm512_fmsub_ps(r_sum, r_sum, sb_jsq); + + two_b_sq = _mm512_max_ps(two_b_sq, v_eps_sq); + + // # 16 SQRTs + __m512 two_b = _mm512_sqrt_ps(two_b_sq); + + // # 16 MULTs + __m512 e_arg = _mm512_mul_ps(two_b, v_neg_2s_inv); + + e_arg = _mm512_max_ps(e_arg, v_exp_min); + + // # 256 MULTs, 224 ADDs + __m512 e_val = _avx512_exp_ps(e_arg); + + // # 64 MULTs + __m512 numer = _mm512_mul_ps(_mm512_mul_ps(r_sum, v_neg_v0_div_2s), e_val); + __m512 denom = _mm512_mul_ps(_mm512_mul_ps(two_b, r_ab_n), r_ab2_n); + + __m512 denom_safe = _mm512_mask_blend_ps(active, v_one, denom); + + // # 16 DIVs + __m512 smc = _mm512_div_ps(numer, denom_safe); + + // # 32 MULTs + __m512 sm_r_ab = _mm512_mul_ps(smc, r_ab2_n); + __m512 sm_r_ab2 = _mm512_mul_ps(smc, r_ab_n); + + // # 64 MULTs, 32 ADDs + __m512 f_x = _mm512_fmadd_ps(r_ab2_x, sm_r_ab2, _mm512_mul_ps(r_ab_x, sm_r_ab)); + __m512 f_y = _mm512_fmadd_ps(r_ab2_y, sm_r_ab2, _mm512_mul_ps(r_ab_y, sm_r_ab)); + + // # 32 MULTs, 16 ADDs + __m512 f_norm_sq = _mm512_fmadd_ps(f_x, f_x, _mm512_mul_ps(f_y, f_y)); + + // # 16 MULTs + __m512 rhs = _mm512_mul_ps(f_norm_sq, v_cos_phi_sq); + + // # 32 MULTs, 16 ADDs + __m512 e_dot_f = _mm512_fmadd_ps(eix, f_x, _mm512_mul_ps(eiy, f_y)); + + // # 16 MULTs + __m512 e_dot_f_sq = _mm512_mul_ps(e_dot_f, e_dot_f); + + __mmask16 c1 = _mm512_cmp_ps_mask(e_dot_f, v_zero, _CMP_LT_OQ); + __mmask16 c2 = _mm512_cmp_ps_mask(e_dot_f_sq, rhs, _CMP_GT_OQ); + __mmask16 cond = c1 & c2; + + __m512 w_val = _mm512_mask_blend_ps(cond, v_dt_neg, v_c_neg_dt); + + __m512 f_x_safe = _mm512_maskz_mov_ps(active, f_x); + __m512 f_y_safe = _mm512_maskz_mov_ps(active, f_y); + + // # 32 MULTs, 32 ADDs + acc_x = _mm512_fmadd_ps(f_x_safe, w_val, acc_x); + acc_y = _mm512_fmadd_ps(f_y_safe, w_val, acc_y); + } + + // # 32 ADDs + f_alpha_dt_x += _mm512_reduce_add_ps(acc_x); + f_alpha_dt_y += _mm512_reduce_add_ps(acc_y); + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + float v1_x = pos_x[i] - board.obstacles[k].start_x; + float v1_y = pos_y[i] - board.obstacles[k].start_y; + float v2_x = board.obstacles[k].obstacle_v_x; + float v2_y = board.obstacles[k].obstacle_v_y; + + // # 3 MULTs, 1 ADD + float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0f) + projection = 0.0f; + else if (projection > 1.0f) + projection = 1.0f; + + // # 4 ADDs, 2 MULTs + float r_aB_x = pos_x[i] - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + float r_aB_y = pos_y[i] - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + + // # 2 MULTs, 1 EXP, 1 DIV + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + + // # 2 MULTs + float f_alpha_B_neg_x = r_aB_x * scalar_mult; + float f_alpha_B_neg_y = r_aB_y * scalar_mult; + + float w_val = dt_neg; + float e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y[i] : e_y[i]); + + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTs + float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p; i++) { + // # 9 MULTs, 3 ADDs + float w_norm_inv = fast_inv_sqrt(w_x[i] * w_x[i] + w_y[i] * w_y[i]); + + // # 1 MULT + float correction_factor = min(1.0f, v_max[i] * w_norm_inv); + + // # 2 MULTs + curr_vel_x[i] = w_x[i] * correction_factor; + curr_vel_y[i] = w_y[i] * correction_factor; + + // # 2 MULTs, 2 ADDs + pos_x[i] = pos_x[i] + curr_vel_x[i] * dt; + pos_y[i] = pos_y[i] + curr_vel_y[i] * dt; + + if (color[i] == 0 && pos_x[i] > (BOARD_LENGTH_MINUS_ONE_POINT_FIVE)) { + pos_x[i] = 1.0f; + destination_y[i] = pos_y[i]; + w_x[i] = desired_v0[i]; + w_y[i] = 0.0f; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + if (color[i] == 1 && pos_x[i] < 1.5f) { + pos_x[i] = BOARD_LENGTH_MINUS_ONE; + destination_y[i] = pos_y[i]; + w_x[i] = -desired_v0[i]; + w_y[i] = 0.0f; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + + pos_y[i] = clamp(pos_y[i], WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + // # 2 ADDs + float ex = destination_x[i] - pos_x[i]; + float ey = destination_y[i] - pos_y[i]; + + // # 9 MULTs, 3 ADDs + float e_norm_inv = fast_inv_sqrt(ex * ex + ey * ey); + + // # 2 MULTs + e_x[i] = ex * e_norm_inv; + e_y[i] = ey * e_norm_inv; + + // # 2 MULTs, 1 ADD + double velocity_norm_sq = curr_vel_x[i] * curr_vel_x[i] + curr_vel_y[i] * curr_vel_y[i]; + + // # 1 MULT + double sb_sq_i = velocity_norm_sq * delta_t_sq; + + // # 1 SQRT + double velocity_norm_mul_delta_t = sqrt(sb_sq_i); + + sb_sq[i] = sb_sq_i; + + // # 2 MULTs + sb_e_x[i] = e_x[i] * velocity_norm_mul_delta_t; + sb_e_y[i] = e_y[i] * velocity_norm_mul_delta_t; + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix.cpp new file mode 100644 index 0000000..720810a --- /dev/null +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_expfix.cpp @@ -0,0 +1,577 @@ +// # Changes: Added more correction rounds to _avx512_exp_ps to do 30 flops per scalar +// # Predecessor: variant_float_inlining_SoA_AVX512_polyexp_moreavx.cpp + +#include "../headers/board_reduced_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_reduced_float.hpp" + +#include + +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0f +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 15) & ~15; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + float dest_x = BOARD_LENGTH + 30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + float dest_x = -30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9f; + pos_y[j] = 1e9f; + sb_sq[j] = 0.0f; + sb_e_x[j] = 0.0f; + sb_e_y[j] = 0.0f; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 256 MULTs, 224 ADDs +static inline __m512 _avx512_exp_ps(__m512 x) { + + const __m512 log2e = _mm512_set1_ps(1.4426950408889634f); + + // # 16 MULTs + __m512 nf = _mm512_roundscale_ps(_mm512_mul_ps(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + + const __m512 ln2 = _mm512_set1_ps(0.6931471805599453f); + + // # 16 MULTs, 16 ADDs + __m512 r = _mm512_fnmadd_ps(nf, ln2, x); + + const __m512 c13 = _mm512_set1_ps(c13_scalar); + const __m512 c12 = _mm512_set1_ps(c12_scalar); + const __m512 c11 = _mm512_set1_ps(c11_scalar); + const __m512 c10 = _mm512_set1_ps(c10_scalar); + const __m512 c9 = _mm512_set1_ps(c9_scalar); + const __m512 c8 = _mm512_set1_ps(c8_scalar); + const __m512 c7 = _mm512_set1_ps(c7_scalar); + const __m512 c6 = _mm512_set1_ps(c6_scalar); + const __m512 c5 = _mm512_set1_ps(c5_scalar); + const __m512 c4 = _mm512_set1_ps(c4_scalar); + const __m512 c3 = _mm512_set1_ps(c3_scalar); + const __m512 c2 = _mm512_set1_ps(c2_scalar); + const __m512 c1 = _mm512_set1_ps(c1_scalar); + const __m512 c0 = _mm512_set1_ps(c0_scalar); + + __m512 p = c13; + + // # 13 * (16 MULTs, 16 ADDs) + // # = 208 MULTs, 208 ADDs + p = _mm512_fmadd_ps(p, r, c12); + p = _mm512_fmadd_ps(p, r, c11); + p = _mm512_fmadd_ps(p, r, c10); + p = _mm512_fmadd_ps(p, r, c9); + p = _mm512_fmadd_ps(p, r, c8); + p = _mm512_fmadd_ps(p, r, c7); + p = _mm512_fmadd_ps(p, r, c6); + p = _mm512_fmadd_ps(p, r, c5); + p = _mm512_fmadd_ps(p, r, c4); + p = _mm512_fmadd_ps(p, r, c3); + p = _mm512_fmadd_ps(p, r, c2); + p = _mm512_fmadd_ps(p, r, c1); + p = _mm512_fmadd_ps(p, r, c0); + + __m512i ni = _mm512_cvtps_epi32(nf); + __m512i biased = _mm512_add_epi32(ni, _mm512_set1_epi32(127)); + __m512i scaled = _mm512_slli_epi32(biased, 23); + __m512 pow2n = _mm512_castsi512_ps(scaled); + + // # 16 MULTs + return _mm512_mul_ps(p, pow2n); +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + (void)pedestrians; +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 15) & ~15; + + alignas(64) const float lane_offset_arr[16] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f}; + const __m512 lane_off = _mm512_load_ps(lane_offset_arr); + + const __m512 v_neg_v0_div_2s = _mm512_set1_ps(NEG_V0_AB_div_TWO_SIGMA); + const __m512 v_neg_2s_inv = _mm512_set1_ps(NEG_TWO_SIGMA_INV); + const __m512 v_cos_phi_sq = _mm512_set1_ps(cos_phi_sq); + const __m512 v_dt_neg = _mm512_set1_ps(dt_neg); + const __m512 v_c_neg_dt = _mm512_set1_ps(c_neg_times_dt); + const __m512 v_zero = _mm512_setzero_ps(); + const __m512 v_one = _mm512_set1_ps(1.0f); + const __m512 v_eps = _mm512_set1_ps(EPS); + const __m512 v_eps_sq = _mm512_set1_ps(EPS_SQ); + const __m512 v_np = _mm512_set1_ps((float)n_p); + const __m512 v_exp_min = _mm512_set1_ps(-87.0f); + + // # ADDs: n_iter * ( + // # n_p * 36 + + // # n_p * n_p_pad * 29 + + // # n_p * board.n_obstacles * 10 + + // # n_p_pad * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + + // # n_p * n_p_pad * 40 + + // # n_p * board.n_obstacles * 13 + + // # n_p_pad * 15 + // # ) + + // # DIVs: n_iter * ( + // # n_p * n_p_pad + + // # n_p * board.n_obstacles + + // # n_p_pad * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * n_p_pad * 3 + + // # n_p * board.n_obstacles + + // # n_p_pad * 3 + // # ) + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + + // # 2 MULTs + float desired_velocity_x = e_x[i] * desired_v0[i]; + float desired_velocity_y = e_y[i] * desired_v0[i]; + + // # 2 ADDs, 2 MULTs + float f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; + float f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; + + const __m512 pix = _mm512_set1_ps(pos_x[i]); + const __m512 piy = _mm512_set1_ps(pos_y[i]); + const __m512 eix = _mm512_set1_ps(e_x[i]); + const __m512 eiy = _mm512_set1_ps(e_y[i]); + const __m512 v_i = _mm512_set1_ps((float)i); + + __m512 acc_x = _mm512_setzero_ps(); + __m512 acc_y = _mm512_setzero_ps(); + + for (int j = 0; j < n_p_pad; j += 16) { + + // # 16 ADDs + __m512 j_idx = _mm512_add_ps(_mm512_set1_ps((float)j), lane_off); + + __mmask16 m_neq_i = _mm512_cmp_ps_mask(j_idx, v_i, _CMP_NEQ_OQ); + __mmask16 m_in_range = _mm512_cmp_ps_mask(j_idx, v_np, _CMP_LT_OQ); + __mmask16 active = m_neq_i & m_in_range; + + __m512 pjx = _mm512_loadu_ps(&pos_x[j]); + __m512 pjy = _mm512_loadu_ps(&pos_y[j]); + __m512 sbe_jx = _mm512_loadu_ps(&sb_e_x[j]); + __m512 sbe_jy = _mm512_loadu_ps(&sb_e_y[j]); + __m512 sb_jsq = _mm512_loadu_ps(&sb_sq[j]); + + // # 32 ADDs + __m512 r_ab_x = _mm512_sub_ps(pix, pjx); + __m512 r_ab_y = _mm512_sub_ps(piy, pjy); + + // # 32 MULTs, 16 ADDs + __m512 r_ab_n2 = _mm512_fmadd_ps(r_ab_x, r_ab_x, _mm512_mul_ps(r_ab_y, r_ab_y)); + + // # 16 SQRTs + __m512 r_ab_n = _mm512_sqrt_ps(r_ab_n2); + + r_ab_n = _mm512_max_ps(r_ab_n, v_eps); + + // # 32 ADDs + __m512 r_ab2_x = _mm512_sub_ps(r_ab_x, sbe_jx); + __m512 r_ab2_y = _mm512_sub_ps(r_ab_y, sbe_jy); + + // # 32 MULTs, 16 ADDs + __m512 r_ab2_n2 = _mm512_fmadd_ps(r_ab2_x, r_ab2_x, _mm512_mul_ps(r_ab2_y, r_ab2_y)); + + // # 16 SQRTs + __m512 r_ab2_n = _mm512_sqrt_ps(r_ab2_n2); + + r_ab2_n = _mm512_max_ps(r_ab2_n, v_eps); + + // # 16 ADDs + __m512 r_sum = _mm512_add_ps(r_ab_n, r_ab2_n); + + // # 16 MULTs, 16 ADDs + __m512 two_b_sq = _mm512_fmsub_ps(r_sum, r_sum, sb_jsq); + + two_b_sq = _mm512_max_ps(two_b_sq, v_eps_sq); + + // # 16 SQRTs + __m512 two_b = _mm512_sqrt_ps(two_b_sq); + + // # 16 MULTs + __m512 e_arg = _mm512_mul_ps(two_b, v_neg_2s_inv); + + e_arg = _mm512_max_ps(e_arg, v_exp_min); + + // # 256 MULTs, 224 ADDs + __m512 e_val = _avx512_exp_ps(e_arg); + + // # 64 MULTs + __m512 numer = _mm512_mul_ps(_mm512_mul_ps(r_sum, v_neg_v0_div_2s), e_val); + __m512 denom = _mm512_mul_ps(_mm512_mul_ps(two_b, r_ab_n), r_ab2_n); + __m512 denom_safe = _mm512_mask_blend_ps(active, v_one, denom); + + // # 16 DIVs + __m512 smc = _mm512_div_ps(numer, denom_safe); + + // # 32 MULTs + __m512 sm_r_ab = _mm512_mul_ps(smc, r_ab2_n); + __m512 sm_r_ab2 = _mm512_mul_ps(smc, r_ab_n); + + // # 64 MULTs, 32 ADDs + __m512 f_x = _mm512_fmadd_ps(r_ab2_x, sm_r_ab2, _mm512_mul_ps(r_ab_x, sm_r_ab)); + __m512 f_y = _mm512_fmadd_ps(r_ab2_y, sm_r_ab2, _mm512_mul_ps(r_ab_y, sm_r_ab)); + + // # 32 MULTs, 16 ADDs + __m512 f_norm_sq = _mm512_fmadd_ps(f_x, f_x, _mm512_mul_ps(f_y, f_y)); + + // # 16 MULTs + __m512 rhs = _mm512_mul_ps(f_norm_sq, v_cos_phi_sq); + + // # 32 MULTs, 16 ADDs + __m512 e_dot_f = _mm512_fmadd_ps(eix, f_x, _mm512_mul_ps(eiy, f_y)); + + // # 16 MULTs + __m512 e_dot_f_sq = _mm512_mul_ps(e_dot_f, e_dot_f); + + __mmask16 c1 = _mm512_cmp_ps_mask(e_dot_f, v_zero, _CMP_LT_OQ); + __mmask16 c2 = _mm512_cmp_ps_mask(e_dot_f_sq, rhs, _CMP_GT_OQ); + __mmask16 cond = c1 & c2; + + __m512 w_val = _mm512_mask_blend_ps(cond, v_dt_neg, v_c_neg_dt); + + __m512 f_x_safe = _mm512_maskz_mov_ps(active, f_x); + __m512 f_y_safe = _mm512_maskz_mov_ps(active, f_y); + + // # 32 MULTs, 32 ADDs + acc_x = _mm512_fmadd_ps(f_x_safe, w_val, acc_x); + acc_y = _mm512_fmadd_ps(f_y_safe, w_val, acc_y); + } + + // # 32 ADDs + f_alpha_dt_x += _mm512_reduce_add_ps(acc_x); + f_alpha_dt_y += _mm512_reduce_add_ps(acc_y); + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + float v1_x = pos_x[i] - board.obstacles[k].start_x; + float v1_y = pos_y[i] - board.obstacles[k].start_y; + float v2_x = board.obstacles[k].obstacle_v_x; + float v2_y = board.obstacles[k].obstacle_v_y; + + // # 3 MULTs, 1 ADD + float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0f) + projection = 0.0f; + else if (projection > 1.0f) + projection = 1.0f; + + // # 4 ADDs, 2 MULTs + float r_aB_x = pos_x[i] - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + float r_aB_y = pos_y[i] - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; + + // # 4 MULTs, 1 EXP, 1 DIV + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + float f_alpha_B_neg_x = r_aB_x * scalar_mult; + float f_alpha_B_neg_y = r_aB_y * scalar_mult; + + float w_val = dt_neg; + float e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y[i] : e_y[i]); + + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTS + float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p_pad; i += 16) { + __m512 w_x_i_vec = _mm512_loadu_ps(&w_x[i]); + __m512 w_y_i_vec = _mm512_loadu_ps(&w_y[i]); + __m512 v_max_i_vec = _mm512_loadu_ps(&v_max[i]); + __m512 pos_x_i_vec = _mm512_loadu_ps(&pos_x[i]); + __m512 pos_y_i_vec = _mm512_loadu_ps(&pos_y[i]); + __m512 destination_y_i_vec = _mm512_loadu_ps(&destination_y[i]); + __m512 destination_x_i_vec = _mm512_loadu_ps(&destination_x[i]); + __m512 desired_v0_i_vec = _mm512_loadu_ps(&desired_v0[i]); + + __m512i color_i_vec = _mm512_loadu_si512((__m512i *)&color[i]); + + // # 32 MULTs, 16 ADDs + __m512 w_norm_sq = _mm512_fmadd_ps(w_x_i_vec, w_x_i_vec, _mm512_mul_ps(w_y_i_vec, w_y_i_vec)); + + // # 16 SQRTs + __m512 w_norm = _mm512_sqrt_ps(w_norm_sq); + __m512 w_norm_safe = _mm512_max_ps(w_norm, _mm512_set1_ps(EPS)); + + // # 16 DIVs + __m512 correction_factor = _mm512_min_ps(_mm512_set1_ps(1.0f), _mm512_div_ps(v_max_i_vec, w_norm_safe)); + + // # 32 MULTs + __m512 curr_vel_x_i_vec = _mm512_mul_ps(w_x_i_vec, correction_factor); + __m512 curr_vel_y_i_vec = _mm512_mul_ps(w_y_i_vec, correction_factor); + + __m512 dt_vec = _mm512_set1_ps(dt); + + // # 32 MULTs, 32 ADDs + pos_x_i_vec = _mm512_fmadd_ps(curr_vel_x_i_vec, dt_vec, pos_x_i_vec); + pos_y_i_vec = _mm512_fmadd_ps(curr_vel_y_i_vec, dt_vec, pos_y_i_vec); + + __mmask16 cond_1_left = _mm512_cmpeq_epi32_mask(color_i_vec, _mm512_setzero_si512()); + __mmask16 cond_1_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE_POINT_FIVE), _CMP_GT_OQ); + __mmask16 cond_1 = cond_1_left & cond_1_right; + + pos_x_i_vec = _mm512_mask_blend_ps(cond_1, pos_x_i_vec, _mm512_set1_ps(1.0f)); + destination_y_i_vec = _mm512_mask_blend_ps(cond_1, destination_y_i_vec, pos_y_i_vec); + w_x_i_vec = _mm512_mask_blend_ps(cond_1, w_x_i_vec, desired_v0_i_vec); + w_y_i_vec = _mm512_mask_blend_ps(cond_1, w_y_i_vec, _mm512_setzero_ps()); + curr_vel_x_i_vec = _mm512_mask_blend_ps(cond_1, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_ps(cond_1, curr_vel_y_i_vec, w_y_i_vec); + + __mmask16 cond_2_left = _mm512_cmpeq_epi32_mask(color_i_vec, _mm512_set1_epi32(1)); + __mmask16 cond_2_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(1.5f), _CMP_LT_OQ); + __mmask16 cond_2 = cond_2_left & cond_2_right; + + pos_x_i_vec = _mm512_mask_blend_ps(cond_2, pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE)); + destination_y_i_vec = _mm512_mask_blend_ps(cond_2, destination_y_i_vec, pos_y_i_vec); + __m512 neg_desired_v0 = _mm512_xor_ps(desired_v0_i_vec, _mm512_set1_ps(-0.0f)); + w_x_i_vec = _mm512_mask_blend_ps(cond_2, w_x_i_vec, neg_desired_v0); + w_y_i_vec = _mm512_mask_blend_ps(cond_2, w_y_i_vec, _mm512_setzero_ps()); + curr_vel_x_i_vec = _mm512_mask_blend_ps(cond_2, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_ps(cond_2, curr_vel_y_i_vec, w_y_i_vec); + + pos_y_i_vec = _mm512_max_ps(pos_y_i_vec, _mm512_set1_ps(WALL_EPS)); + pos_y_i_vec = _mm512_min_ps(pos_y_i_vec, _mm512_set1_ps(BOARD_WIDTH_MINUS_WALL_EPS)); + + // # 32 ADDs + __m512 ex_vec = _mm512_sub_ps(destination_x_i_vec, pos_x_i_vec); + __m512 ey_vec = _mm512_sub_ps(destination_y_i_vec, pos_y_i_vec); + + // # 32 MULTs, 16 ADDs + __m512 e_norm_sq = _mm512_fmadd_ps(ex_vec, ex_vec, _mm512_mul_ps(ey_vec, ey_vec)); + + // # 16 SQRTs + __m512 e_norm = _mm512_sqrt_ps(e_norm_sq); + + // # 16 DIVs + __m512 e_norm_inv = _mm512_div_ps(_mm512_set1_ps(1.0f), e_norm); + + // # 32 MULTs + __m512 e_x_i_vec = _mm512_mul_ps(ex_vec, e_norm_inv); + __m512 e_y_i_vec = _mm512_mul_ps(ey_vec, e_norm_inv); + + // # 32 MULTs, 16 ADDs + __m512 vel_norm_sq = _mm512_fmadd_ps(curr_vel_x_i_vec, curr_vel_x_i_vec, _mm512_mul_ps(curr_vel_y_i_vec, curr_vel_y_i_vec)); + + // # 16 MULTs + __m512 sb_sq_i_vec = _mm512_mul_ps(vel_norm_sq, _mm512_set1_ps(delta_t_sq)); + + // # 16 SQRTs + __m512 vel_norm_dt = _mm512_sqrt_ps(sb_sq_i_vec); + + _mm512_storeu_ps(&curr_vel_x[i], curr_vel_x_i_vec); + _mm512_storeu_ps(&curr_vel_y[i], curr_vel_y_i_vec); + _mm512_storeu_ps(&w_x[i], w_x_i_vec); + _mm512_storeu_ps(&w_y[i], w_y_i_vec); + _mm512_storeu_ps(&pos_x[i], pos_x_i_vec); + _mm512_storeu_ps(&pos_y[i], pos_y_i_vec); + _mm512_storeu_ps(&e_x[i], e_x_i_vec); + _mm512_storeu_ps(&e_y[i], e_y_i_vec); + _mm512_storeu_ps(&destination_y[i], destination_y_i_vec); + _mm512_storeu_ps(&sb_sq[i], sb_sq_i_vec); + + // # 32 MULTs + _mm512_storeu_ps(&sb_e_x[i], _mm512_mul_ps(e_x_i_vec, vel_norm_dt)); + _mm512_storeu_ps(&sb_e_y[i], _mm512_mul_ps(e_y_i_vec, vel_norm_dt)); + } + +#if !BENCHMARK + for (int i = 0; i < n_p; i++) { + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp new file mode 100644 index 0000000..85eac51 --- /dev/null +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp @@ -0,0 +1,638 @@ +// # Changes: Added ILP with k = 2 to j-loop, removed EPS checks where possible +// # Predecessor: variant_float_inlining_SoA_AVX512_polyexp_moreavx.cpp + +#include "../headers/board_reduced_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_reduced_float.hpp" + +#include + +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0f +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 31) & ~31; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + float dest_x = BOARD_LENGTH + 30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + float dest_x = -30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9f; + pos_y[j] = 1e9f; + sb_sq[j] = 0.0f; + sb_e_x[j] = 0.0f; + sb_e_y[j] = 0.0f; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 256 MULTs, 224 ADDs +static inline __m512 _avx512_exp_ps(__m512 x) { + + const __m512 log2e = _mm512_set1_ps(1.4426950408889634f); + + // # 16 MULTs + __m512 nf = _mm512_roundscale_ps(_mm512_mul_ps(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + + const __m512 ln2 = _mm512_set1_ps(0.6931471805599453f); + + // # 16 MULTs, 16 ADDs + __m512 r = _mm512_fnmadd_ps(nf, ln2, x); + + const __m512 c13 = _mm512_set1_ps(c13_scalar); + const __m512 c12 = _mm512_set1_ps(c12_scalar); + const __m512 c11 = _mm512_set1_ps(c11_scalar); + const __m512 c10 = _mm512_set1_ps(c10_scalar); + const __m512 c9 = _mm512_set1_ps(c9_scalar); + const __m512 c8 = _mm512_set1_ps(c8_scalar); + const __m512 c7 = _mm512_set1_ps(c7_scalar); + const __m512 c6 = _mm512_set1_ps(c6_scalar); + const __m512 c5 = _mm512_set1_ps(c5_scalar); + const __m512 c4 = _mm512_set1_ps(c4_scalar); + const __m512 c3 = _mm512_set1_ps(c3_scalar); + const __m512 c2 = _mm512_set1_ps(c2_scalar); + const __m512 c1 = _mm512_set1_ps(c1_scalar); + const __m512 c0 = _mm512_set1_ps(c0_scalar); + + __m512 p = c13; + + // # 13 * (16 MULTs, 16 ADDs) + // # = 208 MULTs, 208 ADDs + p = _mm512_fmadd_ps(p, r, c12); + p = _mm512_fmadd_ps(p, r, c11); + p = _mm512_fmadd_ps(p, r, c10); + p = _mm512_fmadd_ps(p, r, c9); + p = _mm512_fmadd_ps(p, r, c8); + p = _mm512_fmadd_ps(p, r, c7); + p = _mm512_fmadd_ps(p, r, c6); + p = _mm512_fmadd_ps(p, r, c5); + p = _mm512_fmadd_ps(p, r, c4); + p = _mm512_fmadd_ps(p, r, c3); + p = _mm512_fmadd_ps(p, r, c2); + p = _mm512_fmadd_ps(p, r, c1); + p = _mm512_fmadd_ps(p, r, c0); + + __m512i ni = _mm512_cvtps_epi32(nf); + __m512i biased = _mm512_add_epi32(ni, _mm512_set1_epi32(127)); + __m512i scaled = _mm512_slli_epi32(biased, 23); + __m512 pow2n = _mm512_castsi512_ps(scaled); + + // # 16 MULTs + return _mm512_mul_ps(p, pow2n); +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + (void)pedestrians; +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 31) & ~31; + + alignas(64) const float lane_offset_arr[16] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f}; + const __m512 lane_off = _mm512_load_ps(lane_offset_arr); + + const __m512 v_neg_v0_div_2s = _mm512_set1_ps(NEG_V0_AB_div_TWO_SIGMA); + const __m512 v_neg_2s_inv = _mm512_set1_ps(NEG_TWO_SIGMA_INV); + const __m512 v_cos_phi_sq = _mm512_set1_ps(cos_phi_sq); + const __m512 v_dt_neg = _mm512_set1_ps(dt_neg); + const __m512 v_c_neg_dt = _mm512_set1_ps(c_neg_times_dt); + const __m512 v_zero = _mm512_setzero_ps(); + const __m512 v_one = _mm512_set1_ps(1.0f); + const __m512 v_eps = _mm512_set1_ps(EPS); + const __m512 v_eps_sq = _mm512_set1_ps(EPS_SQ); + const __m512 v_np = _mm512_set1_ps((float)n_p); + const __m512 v_exp_min = _mm512_set1_ps(-87.0f); + + // # ADDs: n_iter * ( + // # n_p * 68 + + // # n_p * n_p_pad * 29 + + // # n_p * board.n_obstacles * 10 + + // # n_p_pad * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + + // # n_p * n_p_pad * 40 + + // # n_p * board.n_obstacles * 13 + + // # n_p_pad * 15 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * n_p_pad * 3 + + // # n_p * board.n_obstacles + + // # n_p_pad * 3 + // # ) + + // # DIVs: n_iter * ( + // # n_p * n_p_pad + + // # n_p * board.n_obstacles + + // # n_p_pad * 2 + // # ) + + // # EXPs: n_iter * n_p * board.n_obstacles + + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + + // # 2 MULTs + float desired_velocity_x = e_x[i] * desired_v0[i]; + float desired_velocity_y = e_y[i] * desired_v0[i]; + + // # 2 ADDs, 2 MULTs + float f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; + float f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; + + const __m512 pix = _mm512_set1_ps(pos_x[i]); + const __m512 piy = _mm512_set1_ps(pos_y[i]); + const __m512 eix = _mm512_set1_ps(e_x[i]); + const __m512 eiy = _mm512_set1_ps(e_y[i]); + const __m512 v_i = _mm512_set1_ps((float)i); + + __m512 acc_x_0 = _mm512_setzero_ps(); + __m512 acc_y_0 = _mm512_setzero_ps(); + __m512 acc_x_1 = _mm512_setzero_ps(); + __m512 acc_y_1 = _mm512_setzero_ps(); + + for (int j = 0; j < n_p_pad; j += 32) { + + // # 32 ADDs + __m512 j_idx_0 = _mm512_add_ps(_mm512_set1_ps((float)j), lane_off); + __m512 j_idx_1 = _mm512_add_ps(_mm512_set1_ps((float)j + 16), lane_off); + + __mmask16 m_neq_i_0 = _mm512_cmp_ps_mask(j_idx_0, v_i, _CMP_NEQ_OQ); + __mmask16 m_neq_i_1 = _mm512_cmp_ps_mask(j_idx_1, v_i, _CMP_NEQ_OQ); + + __mmask16 m_in_range_0 = _mm512_cmp_ps_mask(j_idx_0, v_np, _CMP_LT_OQ); + __mmask16 m_in_range_1 = _mm512_cmp_ps_mask(j_idx_1, v_np, _CMP_LT_OQ); + + __mmask16 active_0 = m_neq_i_0 & m_in_range_0; + __mmask16 active_1 = m_neq_i_1 & m_in_range_1; + + __m512 pjx_0 = _mm512_loadu_ps(&pos_x[j]); + __m512 pjx_1 = _mm512_loadu_ps(&pos_x[j + 16]); + + __m512 pjy_0 = _mm512_loadu_ps(&pos_y[j]); + __m512 pjy_1 = _mm512_loadu_ps(&pos_y[j + 16]); + + __m512 sbe_jx_0 = _mm512_loadu_ps(&sb_e_x[j]); + __m512 sbe_jx_1 = _mm512_loadu_ps(&sb_e_x[j + 16]); + + __m512 sbe_jy_0 = _mm512_loadu_ps(&sb_e_y[j]); + __m512 sbe_jy_1 = _mm512_loadu_ps(&sb_e_y[j + 16]); + + __m512 sb_jsq_0 = _mm512_loadu_ps(&sb_sq[j]); + __m512 sb_jsq_1 = _mm512_loadu_ps(&sb_sq[j + 16]); + + // # 32 ADDs + __m512 r_ab_x_0 = _mm512_sub_ps(pix, pjx_0); + __m512 r_ab_x_1 = _mm512_sub_ps(pix, pjx_1); + + // # 32 ADDs + __m512 r_ab_y_0 = _mm512_sub_ps(piy, pjy_0); + __m512 r_ab_y_1 = _mm512_sub_ps(piy, pjy_1); + + // # 64 MULTs, 32 ADDs + __m512 r_ab_n2_0 = _mm512_fmadd_ps(r_ab_x_0, r_ab_x_0, _mm512_mul_ps(r_ab_y_0, r_ab_y_0)); + __m512 r_ab_n2_1 = _mm512_fmadd_ps(r_ab_x_1, r_ab_x_1, _mm512_mul_ps(r_ab_y_1, r_ab_y_1)); + + // # 32 SQRTs + __m512 r_ab_n_0 = _mm512_sqrt_ps(r_ab_n2_0); + __m512 r_ab_n_1 = _mm512_sqrt_ps(r_ab_n2_1); + + // # 32 ADDs + __m512 r_ab2_x_0 = _mm512_sub_ps(r_ab_x_0, sbe_jx_0); + __m512 r_ab2_x_1 = _mm512_sub_ps(r_ab_x_1, sbe_jx_1); + + // # 32 ADDs + __m512 r_ab2_y_0 = _mm512_sub_ps(r_ab_y_0, sbe_jy_0); + __m512 r_ab2_y_1 = _mm512_sub_ps(r_ab_y_1, sbe_jy_1); + + // # 64 MULTs, 32 ADDs + __m512 r_ab2_n2_0 = _mm512_fmadd_ps(r_ab2_x_0, r_ab2_x_0, _mm512_mul_ps(r_ab2_y_0, r_ab2_y_0)); + __m512 r_ab2_n2_1 = _mm512_fmadd_ps(r_ab2_x_1, r_ab2_x_1, _mm512_mul_ps(r_ab2_y_1, r_ab2_y_1)); + + // # 32 SQRTs + __m512 r_ab2_n_0 = _mm512_sqrt_ps(r_ab2_n2_0); + __m512 r_ab2_n_1 = _mm512_sqrt_ps(r_ab2_n2_1); + + // # 32 ADDs + __m512 r_sum_0 = _mm512_add_ps(r_ab_n_0, r_ab2_n_0); + __m512 r_sum_1 = _mm512_add_ps(r_ab_n_1, r_ab2_n_1); + + // # 32 MULTs, 32 ADDs + __m512 two_b_sq_0 = _mm512_fmsub_ps(r_sum_0, r_sum_0, sb_jsq_0); + __m512 two_b_sq_1 = _mm512_fmsub_ps(r_sum_1, r_sum_1, sb_jsq_1); + + // # 32 SQRTs + __m512 two_b_0 = _mm512_sqrt_ps(two_b_sq_0); + __m512 two_b_1 = _mm512_sqrt_ps(two_b_sq_1); + + // # 32 MULTs + __m512 e_arg_0 = _mm512_mul_ps(two_b_0, v_neg_2s_inv); + __m512 e_arg_1 = _mm512_mul_ps(two_b_1, v_neg_2s_inv); + + e_arg_0 = _mm512_max_ps(e_arg_0, v_exp_min); + e_arg_1 = _mm512_max_ps(e_arg_1, v_exp_min); + + // # 512 MULTs, 448 ADDs + __m512 e_val_0 = _avx512_exp_ps(e_arg_0); + __m512 e_val_1 = _avx512_exp_ps(e_arg_1); + + // # 64 MULTs + __m512 numer_0 = _mm512_mul_ps(_mm512_mul_ps(r_sum_0, v_neg_v0_div_2s), e_val_0); + __m512 numer_1 = _mm512_mul_ps(_mm512_mul_ps(r_sum_1, v_neg_v0_div_2s), e_val_1); + + // # 64 MULTs + __m512 denom_0 = _mm512_mul_ps(_mm512_mul_ps(two_b_0, r_ab_n_0), r_ab2_n_0); + __m512 denom_1 = _mm512_mul_ps(_mm512_mul_ps(two_b_1, r_ab_n_1), r_ab2_n_1); + + __m512 denom_safe_0 = _mm512_mask_blend_ps(active_0, v_one, denom_0); + __m512 denom_safe_1 = _mm512_mask_blend_ps(active_1, v_one, denom_1); + + // # 32 DIVs + __m512 smc_0 = _mm512_div_ps(numer_0, denom_safe_0); + __m512 smc_1 = _mm512_div_ps(numer_1, denom_safe_1); + + // # 32 MULTs + __m512 sm_r_ab_0 = _mm512_mul_ps(smc_0, r_ab2_n_0); + __m512 sm_r_ab_1 = _mm512_mul_ps(smc_1, r_ab2_n_1); + + // # 32 MULTs + __m512 sm_r_ab2_0 = _mm512_mul_ps(smc_0, r_ab_n_0); + __m512 sm_r_ab2_1 = _mm512_mul_ps(smc_1, r_ab_n_1); + + // # 64 MULTs, 32 ADDs + __m512 f_x_0 = _mm512_fmadd_ps(r_ab2_x_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_x_0, sm_r_ab_0)); + __m512 f_x_1 = _mm512_fmadd_ps(r_ab2_x_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_x_1, sm_r_ab_1)); + + // # 64 MULTs, 32 ADDs + __m512 f_y_0 = _mm512_fmadd_ps(r_ab2_y_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_y_0, sm_r_ab_0)); + __m512 f_y_1 = _mm512_fmadd_ps(r_ab2_y_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_y_1, sm_r_ab_1)); + + // # 64 MULTs, 32 ADDs + __m512 f_norm_sq_0 = _mm512_fmadd_ps(f_x_0, f_x_0, _mm512_mul_ps(f_y_0, f_y_0)); + __m512 f_norm_sq_1 = _mm512_fmadd_ps(f_x_1, f_x_1, _mm512_mul_ps(f_y_1, f_y_1)); + + // # 32 MULTs + __m512 rhs_0 = _mm512_mul_ps(f_norm_sq_0, v_cos_phi_sq); + __m512 rhs_1 = _mm512_mul_ps(f_norm_sq_1, v_cos_phi_sq); + + // # 64 MULTs, 32 ADDs + __m512 e_dot_f_0 = _mm512_fmadd_ps(eix, f_x_0, _mm512_mul_ps(eiy, f_y_0)); + __m512 e_dot_f_1 = _mm512_fmadd_ps(eix, f_x_1, _mm512_mul_ps(eiy, f_y_1)); + + // # 32 MULTs + __m512 e_dot_f_sq_0 = _mm512_mul_ps(e_dot_f_0, e_dot_f_0); + __m512 e_dot_f_sq_1 = _mm512_mul_ps(e_dot_f_1, e_dot_f_1); + + __mmask16 c1_0 = _mm512_cmp_ps_mask(e_dot_f_0, v_zero, _CMP_LT_OQ); + __mmask16 c1_1 = _mm512_cmp_ps_mask(e_dot_f_1, v_zero, _CMP_LT_OQ); + + __mmask16 c2_0 = _mm512_cmp_ps_mask(e_dot_f_sq_0, rhs_0, _CMP_GT_OQ); + __mmask16 c2_1 = _mm512_cmp_ps_mask(e_dot_f_sq_1, rhs_1, _CMP_GT_OQ); + + __mmask16 cond_0 = c1_0 & c2_0; + __mmask16 cond_1 = c1_1 & c2_1; + + __m512 w_val_0 = _mm512_mask_blend_ps(cond_0, v_dt_neg, v_c_neg_dt); + __m512 w_val_1 = _mm512_mask_blend_ps(cond_1, v_dt_neg, v_c_neg_dt); + + __m512 f_x_safe_0 = _mm512_maskz_mov_ps(active_0, f_x_0); + __m512 f_x_safe_1 = _mm512_maskz_mov_ps(active_1, f_x_1); + + __m512 f_y_safe_0 = _mm512_maskz_mov_ps(active_0, f_y_0); + __m512 f_y_safe_1 = _mm512_maskz_mov_ps(active_1, f_y_1); + + // # 32 MULTs, 32 ADDs + acc_x_0 = _mm512_fmadd_ps(f_x_safe_0, w_val_0, acc_x_0); + acc_x_1 = _mm512_fmadd_ps(f_x_safe_1, w_val_1, acc_x_1); + + // # 32 MULTs, 32 ADDs + acc_y_0 = _mm512_fmadd_ps(f_y_safe_0, w_val_0, acc_y_0); + acc_y_1 = _mm512_fmadd_ps(f_y_safe_1, w_val_1, acc_y_1); + } + + // # 64 ADDs + f_alpha_dt_x += _mm512_reduce_add_ps(_mm512_add_ps(acc_x_0, acc_x_1)); + f_alpha_dt_y += _mm512_reduce_add_ps(_mm512_add_ps(acc_y_0, acc_y_1)); + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + float v1_x = pos_x[i] - board.obstacles[k].start_x; + float v1_y = pos_y[i] - board.obstacles[k].start_y; + float v2_x = board.obstacles[k].obstacle_v_x; + float v2_y = board.obstacles[k].obstacle_v_y; + + // # 3 MULTs, 1 ADD + float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0f) + projection = 0.0f; + else if (projection > 1.0f) + projection = 1.0f; + + // # 4 ADDs, 2 MULTs + float r_aB_x = pos_x[i] - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + float r_aB_y = pos_y[i] - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; + + // # 1 EXP, 4 MULTs, 1 DIV + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + float f_alpha_B_neg_x = r_aB_x * scalar_mult; + float f_alpha_B_neg_y = r_aB_y * scalar_mult; + + float w_val = dt_neg; + float e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y[i] : e_y[i]); + + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTs + float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p_pad; i += 16) { + + __m512 w_x_i_vec = _mm512_loadu_ps(&w_x[i]); + __m512 w_y_i_vec = _mm512_loadu_ps(&w_y[i]); + __m512 v_max_i_vec = _mm512_loadu_ps(&v_max[i]); + __m512 pos_x_i_vec = _mm512_loadu_ps(&pos_x[i]); + __m512 pos_y_i_vec = _mm512_loadu_ps(&pos_y[i]); + __m512 destination_y_i_vec = _mm512_loadu_ps(&destination_y[i]); + __m512 destination_x_i_vec = _mm512_loadu_ps(&destination_x[i]); + __m512 desired_v0_i_vec = _mm512_loadu_ps(&desired_v0[i]); + + __m512i color_i_vec = _mm512_loadu_si512((__m512i*)&color[i]); + + // # 32 MULTs, 16 ADDs + __m512 w_norm_sq = _mm512_fmadd_ps(w_x_i_vec, w_x_i_vec, _mm512_mul_ps(w_y_i_vec, w_y_i_vec)); + + // # 16 SQRTs + __m512 w_norm = _mm512_sqrt_ps(w_norm_sq); + + // # 16 DIVs + __m512 correction_factor = _mm512_min_ps(_mm512_set1_ps(1.0f), _mm512_div_ps(v_max_i_vec, w_norm)); + + // # 32 MULTs + __m512 curr_vel_x_i_vec = _mm512_mul_ps(w_x_i_vec, correction_factor); + __m512 curr_vel_y_i_vec = _mm512_mul_ps(w_y_i_vec, correction_factor); + + __m512 dt_vec = _mm512_set1_ps(dt); + + // # 32 MULTs, 32 ADDs + pos_x_i_vec = _mm512_fmadd_ps(curr_vel_x_i_vec, dt_vec, pos_x_i_vec); + pos_y_i_vec = _mm512_fmadd_ps(curr_vel_y_i_vec, dt_vec, pos_y_i_vec); + + __mmask16 cond_1_left = _mm512_cmpeq_epi32_mask(color_i_vec, _mm512_setzero_si512()); + __mmask16 cond_1_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE_POINT_FIVE), _CMP_GT_OQ); + __mmask16 cond_1 = cond_1_left & cond_1_right; + + pos_x_i_vec = _mm512_mask_blend_ps(cond_1, pos_x_i_vec, _mm512_set1_ps(1.0f)); + destination_y_i_vec = _mm512_mask_blend_ps(cond_1, destination_y_i_vec, pos_y_i_vec); + w_x_i_vec = _mm512_mask_blend_ps(cond_1, w_x_i_vec, desired_v0_i_vec); + w_y_i_vec = _mm512_mask_blend_ps(cond_1, w_y_i_vec, _mm512_setzero_ps()); + curr_vel_x_i_vec = _mm512_mask_blend_ps(cond_1, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_ps(cond_1, curr_vel_y_i_vec, w_y_i_vec); + + __mmask16 cond_2_left = _mm512_cmpeq_epi32_mask(color_i_vec, _mm512_set1_epi32(1)); + __mmask16 cond_2_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(1.5f), _CMP_LT_OQ); + __mmask16 cond_2 = cond_2_left & cond_2_right; + + pos_x_i_vec = _mm512_mask_blend_ps(cond_2, pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE)); + destination_y_i_vec = _mm512_mask_blend_ps(cond_2, destination_y_i_vec, pos_y_i_vec); + __m512 neg_desired_v0 = _mm512_xor_ps(desired_v0_i_vec, _mm512_set1_ps(-0.0f)); + w_x_i_vec = _mm512_mask_blend_ps(cond_2, w_x_i_vec, neg_desired_v0); + w_y_i_vec = _mm512_mask_blend_ps(cond_2, w_y_i_vec, _mm512_setzero_ps()); + curr_vel_x_i_vec = _mm512_mask_blend_ps(cond_2, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_ps(cond_2, curr_vel_y_i_vec, w_y_i_vec); + + pos_y_i_vec = _mm512_max_ps(pos_y_i_vec, _mm512_set1_ps(WALL_EPS)); + pos_y_i_vec = _mm512_min_ps(pos_y_i_vec, _mm512_set1_ps(BOARD_WIDTH_MINUS_WALL_EPS)); + + // # 32 ADDs + __m512 ex_vec = _mm512_sub_ps(destination_x_i_vec, pos_x_i_vec); + __m512 ey_vec = _mm512_sub_ps(destination_y_i_vec, pos_y_i_vec); + + // # 32 MULTs, 16 ADDs + __m512 e_norm_sq = _mm512_fmadd_ps(ex_vec, ex_vec, _mm512_mul_ps(ey_vec, ey_vec)); + + // # 16 SQRTs + __m512 e_norm = _mm512_sqrt_ps(e_norm_sq); + + // # 16 DIVs + __m512 e_norm_inv = _mm512_div_ps(_mm512_set1_ps(1.0f), e_norm); + + // # 32 MULTs + __m512 e_x_i_vec = _mm512_mul_ps(ex_vec, e_norm_inv); + __m512 e_y_i_vec = _mm512_mul_ps(ey_vec, e_norm_inv); + + // # 32 MULTs, 16 ADDs + __m512 vel_norm_sq = _mm512_fmadd_ps(curr_vel_x_i_vec, curr_vel_x_i_vec, _mm512_mul_ps(curr_vel_y_i_vec, curr_vel_y_i_vec)); + + // # 16 MULTs + __m512 sb_sq_i_vec = _mm512_mul_ps(vel_norm_sq, _mm512_set1_ps(delta_t_sq)); + + // # 16 SQRTs + __m512 vel_norm_dt = _mm512_sqrt_ps(sb_sq_i_vec); + + _mm512_storeu_ps(&curr_vel_x[i], curr_vel_x_i_vec); + _mm512_storeu_ps(&curr_vel_y[i], curr_vel_y_i_vec); + _mm512_storeu_ps(&w_x[i], w_x_i_vec); + _mm512_storeu_ps(&w_y[i], w_y_i_vec); + _mm512_storeu_ps(&pos_x[i], pos_x_i_vec); + _mm512_storeu_ps(&pos_y[i], pos_y_i_vec); + _mm512_storeu_ps(&e_x[i], e_x_i_vec); + _mm512_storeu_ps(&e_y[i], e_y_i_vec); + _mm512_storeu_ps(&destination_y[i], destination_y_i_vec); + _mm512_storeu_ps(&sb_sq[i], sb_sq_i_vec); + + // # 32 MULTs + _mm512_storeu_ps(&sb_e_x[i], _mm512_mul_ps(e_x_i_vec, vel_norm_dt)); + _mm512_storeu_ps(&sb_e_y[i], _mm512_mul_ps(e_y_i_vec, vel_norm_dt)); + } + +#if !BENCHMARK + for (int i = 0; i < n_p; i++) { + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix.cpp new file mode 100644 index 0000000..25a468c --- /dev/null +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_moreilp_expfix.cpp @@ -0,0 +1,735 @@ +// # Changes: Added ILP with k = 2 to second pass +// # Predecessor: variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2.cpp + +#include "../headers/board_reduced_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_reduced_float.hpp" + +#include + +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0f +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 31) & ~31; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + float dest_x = BOARD_LENGTH + 30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + float dest_x = -30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9f; + pos_y[j] = 1e9f; + sb_sq[j] = 0.0f; + sb_e_x[j] = 0.0f; + sb_e_y[j] = 0.0f; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 256 MULTs, 224 ADDs +static inline __m512 _avx512_exp_ps(__m512 x) { + + const __m512 log2e = _mm512_set1_ps(1.4426950408889634f); + + // # 16 MULTs + __m512 nf = _mm512_roundscale_ps(_mm512_mul_ps(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + + const __m512 ln2 = _mm512_set1_ps(0.6931471805599453f); + + // # 16 MULTs, 16 ADDs + __m512 r = _mm512_fnmadd_ps(nf, ln2, x); + + const __m512 c13 = _mm512_set1_ps(c13_scalar); + const __m512 c12 = _mm512_set1_ps(c12_scalar); + const __m512 c11 = _mm512_set1_ps(c11_scalar); + const __m512 c10 = _mm512_set1_ps(c10_scalar); + const __m512 c9 = _mm512_set1_ps(c9_scalar); + const __m512 c8 = _mm512_set1_ps(c8_scalar); + const __m512 c7 = _mm512_set1_ps(c7_scalar); + const __m512 c6 = _mm512_set1_ps(c6_scalar); + const __m512 c5 = _mm512_set1_ps(c5_scalar); + const __m512 c4 = _mm512_set1_ps(c4_scalar); + const __m512 c3 = _mm512_set1_ps(c3_scalar); + const __m512 c2 = _mm512_set1_ps(c2_scalar); + const __m512 c1 = _mm512_set1_ps(c1_scalar); + const __m512 c0 = _mm512_set1_ps(c0_scalar); + + __m512 p = c13; + + // # 13 * (16 MULTs, 16 ADDs) + // # = 208 MULTs, 208 ADDs + p = _mm512_fmadd_ps(p, r, c12); + p = _mm512_fmadd_ps(p, r, c11); + p = _mm512_fmadd_ps(p, r, c10); + p = _mm512_fmadd_ps(p, r, c9); + p = _mm512_fmadd_ps(p, r, c8); + p = _mm512_fmadd_ps(p, r, c7); + p = _mm512_fmadd_ps(p, r, c6); + p = _mm512_fmadd_ps(p, r, c5); + p = _mm512_fmadd_ps(p, r, c4); + p = _mm512_fmadd_ps(p, r, c3); + p = _mm512_fmadd_ps(p, r, c2); + p = _mm512_fmadd_ps(p, r, c1); + p = _mm512_fmadd_ps(p, r, c0); + + __m512i ni = _mm512_cvtps_epi32(nf); + __m512i biased = _mm512_add_epi32(ni, _mm512_set1_epi32(127)); + __m512i scaled = _mm512_slli_epi32(biased, 23); + __m512 pow2n = _mm512_castsi512_ps(scaled); + + // # 16 MULTs + return _mm512_mul_ps(p, pow2n); +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + (void)pedestrians; +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 31) & ~31; + + alignas(64) const float lane_offset_arr[16] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f}; + const __m512 lane_off = _mm512_load_ps(lane_offset_arr); + + const __m512 v_neg_v0_div_2s = _mm512_set1_ps(NEG_V0_AB_div_TWO_SIGMA); + const __m512 v_neg_2s_inv = _mm512_set1_ps(NEG_TWO_SIGMA_INV); + const __m512 v_cos_phi_sq = _mm512_set1_ps(cos_phi_sq); + const __m512 v_dt_neg = _mm512_set1_ps(dt_neg); + const __m512 v_c_neg_dt = _mm512_set1_ps(c_neg_times_dt); + const __m512 v_zero = _mm512_setzero_ps(); + const __m512 v_one = _mm512_set1_ps(1.0f); + const __m512 v_eps = _mm512_set1_ps(EPS); + const __m512 v_eps_sq = _mm512_set1_ps(EPS_SQ); + const __m512 v_np = _mm512_set1_ps((float)n_p); + const __m512 v_exp_min = _mm512_set1_ps(-87.0f); + + // # ADDs: n_iter * ( + // # n_p * 68 + + // # n_p * n_p_pad * 29 + + // # n_p * board.n_obstacles * 10 + + // # n_p_pad * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + + // # n_p * n_p_pad * 40 + + // # n_p * board.n_obstacles * 13 + + // # n_p_pad * 15 + // # ) + + // # DIVs: n_iter * ( + // # n_p * n_p_pad + + // # n_p * board.n_obstacles + + // # n_p_pad * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * n_p_pad * 3 + + // # n_p * board.n_obstacles + + // # n_p_pad * 3 + // # ) + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + + // # 2 MULTs + float desired_velocity_x = e_x[i] * desired_v0[i]; + float desired_velocity_y = e_y[i] * desired_v0[i]; + + // # 2 ADDs, 2 MULTs + float f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; + float f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; + + const __m512 pix = _mm512_set1_ps(pos_x[i]); + const __m512 piy = _mm512_set1_ps(pos_y[i]); + const __m512 eix = _mm512_set1_ps(e_x[i]); + const __m512 eiy = _mm512_set1_ps(e_y[i]); + const __m512 v_i = _mm512_set1_ps((float)i); + + __m512 acc_x_0 = _mm512_setzero_ps(); + __m512 acc_y_0 = _mm512_setzero_ps(); + __m512 acc_x_1 = _mm512_setzero_ps(); + __m512 acc_y_1 = _mm512_setzero_ps(); + + for (int j = 0; j < n_p_pad; j += 32) { + + // # 32 ADDs + __m512 j_idx_0 = _mm512_add_ps(_mm512_set1_ps((float)j), lane_off); + __m512 j_idx_1 = _mm512_add_ps(_mm512_set1_ps((float)j + 16), lane_off); + + __mmask16 m_neq_i_0 = _mm512_cmp_ps_mask(j_idx_0, v_i, _CMP_NEQ_OQ); + __mmask16 m_neq_i_1 = _mm512_cmp_ps_mask(j_idx_1, v_i, _CMP_NEQ_OQ); + + __mmask16 m_in_range_0 = _mm512_cmp_ps_mask(j_idx_0, v_np, _CMP_LT_OQ); + __mmask16 m_in_range_1 = _mm512_cmp_ps_mask(j_idx_1, v_np, _CMP_LT_OQ); + + __mmask16 active_0 = m_neq_i_0 & m_in_range_0; + __mmask16 active_1 = m_neq_i_1 & m_in_range_1; + + __m512 pjx_0 = _mm512_loadu_ps(&pos_x[j]); + __m512 pjx_1 = _mm512_loadu_ps(&pos_x[j + 16]); + + __m512 pjy_0 = _mm512_loadu_ps(&pos_y[j]); + __m512 pjy_1 = _mm512_loadu_ps(&pos_y[j + 16]); + + __m512 sbe_jx_0 = _mm512_loadu_ps(&sb_e_x[j]); + __m512 sbe_jx_1 = _mm512_loadu_ps(&sb_e_x[j + 16]); + + __m512 sbe_jy_0 = _mm512_loadu_ps(&sb_e_y[j]); + __m512 sbe_jy_1 = _mm512_loadu_ps(&sb_e_y[j + 16]); + + __m512 sb_jsq_0 = _mm512_loadu_ps(&sb_sq[j]); + __m512 sb_jsq_1 = _mm512_loadu_ps(&sb_sq[j + 16]); + + // # 32 ADDs + __m512 r_ab_x_0 = _mm512_sub_ps(pix, pjx_0); + __m512 r_ab_x_1 = _mm512_sub_ps(pix, pjx_1); + + // # 32 ADDs + __m512 r_ab_y_0 = _mm512_sub_ps(piy, pjy_0); + __m512 r_ab_y_1 = _mm512_sub_ps(piy, pjy_1); + + // # 64 MULTs, 32 ADDs + __m512 r_ab_n2_0 = _mm512_fmadd_ps(r_ab_x_0, r_ab_x_0, _mm512_mul_ps(r_ab_y_0, r_ab_y_0)); + __m512 r_ab_n2_1 = _mm512_fmadd_ps(r_ab_x_1, r_ab_x_1, _mm512_mul_ps(r_ab_y_1, r_ab_y_1)); + + // # 32 SQRTs + __m512 r_ab_n_0 = _mm512_sqrt_ps(r_ab_n2_0); + __m512 r_ab_n_1 = _mm512_sqrt_ps(r_ab_n2_1); + + // # 32 ADDs + __m512 r_ab2_x_0 = _mm512_sub_ps(r_ab_x_0, sbe_jx_0); + __m512 r_ab2_x_1 = _mm512_sub_ps(r_ab_x_1, sbe_jx_1); + + // # 32 ADDs + __m512 r_ab2_y_0 = _mm512_sub_ps(r_ab_y_0, sbe_jy_0); + __m512 r_ab2_y_1 = _mm512_sub_ps(r_ab_y_1, sbe_jy_1); + + // # 64 MULTs, 32 ADDs + __m512 r_ab2_n2_0 = _mm512_fmadd_ps(r_ab2_x_0, r_ab2_x_0, _mm512_mul_ps(r_ab2_y_0, r_ab2_y_0)); + __m512 r_ab2_n2_1 = _mm512_fmadd_ps(r_ab2_x_1, r_ab2_x_1, _mm512_mul_ps(r_ab2_y_1, r_ab2_y_1)); + + // # 32 SQRTs + __m512 r_ab2_n_0 = _mm512_sqrt_ps(r_ab2_n2_0); + __m512 r_ab2_n_1 = _mm512_sqrt_ps(r_ab2_n2_1); + + // # 32 ADDs + __m512 r_sum_0 = _mm512_add_ps(r_ab_n_0, r_ab2_n_0); + __m512 r_sum_1 = _mm512_add_ps(r_ab_n_1, r_ab2_n_1); + + // # 32 MULTs, 32 ADDs + __m512 two_b_sq_0 = _mm512_fmsub_ps(r_sum_0, r_sum_0, sb_jsq_0); + __m512 two_b_sq_1 = _mm512_fmsub_ps(r_sum_1, r_sum_1, sb_jsq_1); + + // # 32 SQRTs + __m512 two_b_0 = _mm512_sqrt_ps(two_b_sq_0); + __m512 two_b_1 = _mm512_sqrt_ps(two_b_sq_1); + + // # 32 MULTs + __m512 e_arg_0 = _mm512_mul_ps(two_b_0, v_neg_2s_inv); + __m512 e_arg_1 = _mm512_mul_ps(two_b_1, v_neg_2s_inv); + + e_arg_0 = _mm512_max_ps(e_arg_0, v_exp_min); + e_arg_1 = _mm512_max_ps(e_arg_1, v_exp_min); + + // # 512 MULTs, 448 ADDs + __m512 e_val_0 = _avx512_exp_ps(e_arg_0); + __m512 e_val_1 = _avx512_exp_ps(e_arg_1); + + // # 64 MULTs + __m512 numer_0 = _mm512_mul_ps(_mm512_mul_ps(r_sum_0, v_neg_v0_div_2s), e_val_0); + __m512 numer_1 = _mm512_mul_ps(_mm512_mul_ps(r_sum_1, v_neg_v0_div_2s), e_val_1); + + // # 64 MULTs + __m512 denom_0 = _mm512_mul_ps(_mm512_mul_ps(two_b_0, r_ab_n_0), r_ab2_n_0); + __m512 denom_1 = _mm512_mul_ps(_mm512_mul_ps(two_b_1, r_ab_n_1), r_ab2_n_1); + + __m512 denom_safe_0 = _mm512_mask_blend_ps(active_0, v_one, denom_0); + __m512 denom_safe_1 = _mm512_mask_blend_ps(active_1, v_one, denom_1); + + // # 32 DIVs + __m512 smc_0 = _mm512_div_ps(numer_0, denom_safe_0); + __m512 smc_1 = _mm512_div_ps(numer_1, denom_safe_1); + + // # 32 MULTs + __m512 sm_r_ab_0 = _mm512_mul_ps(smc_0, r_ab2_n_0); + __m512 sm_r_ab_1 = _mm512_mul_ps(smc_1, r_ab2_n_1); + + // # 32 MULTs + __m512 sm_r_ab2_0 = _mm512_mul_ps(smc_0, r_ab_n_0); + __m512 sm_r_ab2_1 = _mm512_mul_ps(smc_1, r_ab_n_1); + + // # 64 MULTs, 32 ADDs + __m512 f_x_0 = _mm512_fmadd_ps(r_ab2_x_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_x_0, sm_r_ab_0)); + __m512 f_x_1 = _mm512_fmadd_ps(r_ab2_x_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_x_1, sm_r_ab_1)); + + // # 64 MULTs, 32 ADDs + __m512 f_y_0 = _mm512_fmadd_ps(r_ab2_y_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_y_0, sm_r_ab_0)); + __m512 f_y_1 = _mm512_fmadd_ps(r_ab2_y_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_y_1, sm_r_ab_1)); + + // # 64 MULTs, 32 ADDs + __m512 f_norm_sq_0 = _mm512_fmadd_ps(f_x_0, f_x_0, _mm512_mul_ps(f_y_0, f_y_0)); + __m512 f_norm_sq_1 = _mm512_fmadd_ps(f_x_1, f_x_1, _mm512_mul_ps(f_y_1, f_y_1)); + + // # 32 MULTs + __m512 rhs_0 = _mm512_mul_ps(f_norm_sq_0, v_cos_phi_sq); + __m512 rhs_1 = _mm512_mul_ps(f_norm_sq_1, v_cos_phi_sq); + + // # 64 MULTs, 32 ADDs + __m512 e_dot_f_0 = _mm512_fmadd_ps(eix, f_x_0, _mm512_mul_ps(eiy, f_y_0)); + __m512 e_dot_f_1 = _mm512_fmadd_ps(eix, f_x_1, _mm512_mul_ps(eiy, f_y_1)); + + // # 32 MULTs + __m512 e_dot_f_sq_0 = _mm512_mul_ps(e_dot_f_0, e_dot_f_0); + __m512 e_dot_f_sq_1 = _mm512_mul_ps(e_dot_f_1, e_dot_f_1); + + __mmask16 c1_0 = _mm512_cmp_ps_mask(e_dot_f_0, v_zero, _CMP_LT_OQ); + __mmask16 c1_1 = _mm512_cmp_ps_mask(e_dot_f_1, v_zero, _CMP_LT_OQ); + + __mmask16 c2_0 = _mm512_cmp_ps_mask(e_dot_f_sq_0, rhs_0, _CMP_GT_OQ); + __mmask16 c2_1 = _mm512_cmp_ps_mask(e_dot_f_sq_1, rhs_1, _CMP_GT_OQ); + + __mmask16 cond_0 = c1_0 & c2_0; + __mmask16 cond_1 = c1_1 & c2_1; + + __m512 w_val_0 = _mm512_mask_blend_ps(cond_0, v_dt_neg, v_c_neg_dt); + __m512 w_val_1 = _mm512_mask_blend_ps(cond_1, v_dt_neg, v_c_neg_dt); + + __m512 f_x_safe_0 = _mm512_maskz_mov_ps(active_0, f_x_0); + __m512 f_x_safe_1 = _mm512_maskz_mov_ps(active_1, f_x_1); + + __m512 f_y_safe_0 = _mm512_maskz_mov_ps(active_0, f_y_0); + __m512 f_y_safe_1 = _mm512_maskz_mov_ps(active_1, f_y_1); + + // # 32 MULTs, 32 ADDs + acc_x_0 = _mm512_fmadd_ps(f_x_safe_0, w_val_0, acc_x_0); + acc_x_1 = _mm512_fmadd_ps(f_x_safe_1, w_val_1, acc_x_1); + + // # 32 MULTs, 32 ADDs + acc_y_0 = _mm512_fmadd_ps(f_y_safe_0, w_val_0, acc_y_0); + acc_y_1 = _mm512_fmadd_ps(f_y_safe_1, w_val_1, acc_y_1); + } + + // # 64 ADDs + f_alpha_dt_x += _mm512_reduce_add_ps(_mm512_add_ps(acc_x_0, acc_x_1)); + f_alpha_dt_y += _mm512_reduce_add_ps(_mm512_add_ps(acc_y_0, acc_y_1)); + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + float v1_x = pos_x[i] - board.obstacles[k].start_x; + float v1_y = pos_y[i] - board.obstacles[k].start_y; + float v2_x = board.obstacles[k].obstacle_v_x; + float v2_y = board.obstacles[k].obstacle_v_y; + + // # 3 MULTs, 1 ADD + float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0f) + projection = 0.0f; + else if (projection > 1.0f) + projection = 1.0f; + + // # 4 ADDs, 2 MULTs + float r_aB_x = pos_x[i] - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + float r_aB_y = pos_y[i] - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; + + // # 4 MULTs, 1 EXP, 1 DIV + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + float f_alpha_B_neg_x = r_aB_x * scalar_mult; + float f_alpha_B_neg_y = r_aB_y * scalar_mult; + + float w_val = dt_neg; + float e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y[i] : e_y[i]); + + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTS + float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p_pad; i += 32) { + + __m512 w_x_i_vec_0 = _mm512_loadu_ps(&w_x[i]); + __m512 w_x_i_vec_1 = _mm512_loadu_ps(&w_x[i + 16]); + + __m512 w_y_i_vec_0 = _mm512_loadu_ps(&w_y[i]); + __m512 w_y_i_vec_1 = _mm512_loadu_ps(&w_y[i + 16]); + + __m512 v_max_i_vec_0 = _mm512_loadu_ps(&v_max[i]); + __m512 v_max_i_vec_1 = _mm512_loadu_ps(&v_max[i + 16]); + + __m512 pos_x_i_vec_0 = _mm512_loadu_ps(&pos_x[i]); + __m512 pos_x_i_vec_1 = _mm512_loadu_ps(&pos_x[i + 16]); + + __m512 pos_y_i_vec_0 = _mm512_loadu_ps(&pos_y[i]); + __m512 pos_y_i_vec_1 = _mm512_loadu_ps(&pos_y[i + 16]); + + __m512 destination_y_i_vec_0 = _mm512_loadu_ps(&destination_y[i]); + __m512 destination_y_i_vec_1 = _mm512_loadu_ps(&destination_y[i + 16]); + + __m512 destination_x_i_vec_0 = _mm512_loadu_ps(&destination_x[i]); + __m512 destination_x_i_vec_1 = _mm512_loadu_ps(&destination_x[i + 16]); + + __m512 desired_v0_i_vec_0 = _mm512_loadu_ps(&desired_v0[i]); + __m512 desired_v0_i_vec_1 = _mm512_loadu_ps(&desired_v0[i + 16]); + + __m512i color_i_vec_0 = _mm512_loadu_si512((__m512i *)&color[i]); + __m512i color_i_vec_1 = _mm512_loadu_si512((__m512i *)&color[i + 16]); + + // # 64 MULTs, 32 ADDs + __m512 w_norm_sq_0 = _mm512_fmadd_ps(w_x_i_vec_0, w_x_i_vec_0, _mm512_mul_ps(w_y_i_vec_0, w_y_i_vec_0)); + __m512 w_norm_sq_1 = _mm512_fmadd_ps(w_x_i_vec_1, w_x_i_vec_1, _mm512_mul_ps(w_y_i_vec_1, w_y_i_vec_1)); + + // # 32 SQRTs + __m512 w_norm_0 = _mm512_sqrt_ps(w_norm_sq_0); + __m512 w_norm_1 = _mm512_sqrt_ps(w_norm_sq_1); + + // # 32 DIVs + __m512 correction_factor_0 = _mm512_min_ps(_mm512_set1_ps(1.0f), _mm512_div_ps(v_max_i_vec_0, w_norm_0)); + __m512 correction_factor_1 = _mm512_min_ps(_mm512_set1_ps(1.0f), _mm512_div_ps(v_max_i_vec_1, w_norm_1)); + + // # 32 MULTs + __m512 curr_vel_x_i_vec_0 = _mm512_mul_ps(w_x_i_vec_0, correction_factor_0); + __m512 curr_vel_x_i_vec_1 = _mm512_mul_ps(w_x_i_vec_1, correction_factor_1); + + // # 32 MULTs + __m512 curr_vel_y_i_vec_0 = _mm512_mul_ps(w_y_i_vec_0, correction_factor_0); + __m512 curr_vel_y_i_vec_1 = _mm512_mul_ps(w_y_i_vec_1, correction_factor_1); + + __m512 dt_vec = _mm512_set1_ps(dt); + + // # 32 MULTs, 32 ADDs + pos_x_i_vec_0 = _mm512_fmadd_ps(curr_vel_x_i_vec_0, dt_vec, pos_x_i_vec_0); + pos_x_i_vec_1 = _mm512_fmadd_ps(curr_vel_x_i_vec_1, dt_vec, pos_x_i_vec_1); + + // # 32 MULTs, 32 ADDs + pos_y_i_vec_0 = _mm512_fmadd_ps(curr_vel_y_i_vec_0, dt_vec, pos_y_i_vec_0); + pos_y_i_vec_1 = _mm512_fmadd_ps(curr_vel_y_i_vec_1, dt_vec, pos_y_i_vec_1); + + __mmask16 cond_1_left_0 = _mm512_cmpeq_epi32_mask(color_i_vec_0, _mm512_setzero_si512()); + __mmask16 cond_1_left_1 = _mm512_cmpeq_epi32_mask(color_i_vec_1, _mm512_setzero_si512()); + + __mmask16 cond_1_right_0 = _mm512_cmp_ps_mask(pos_x_i_vec_0, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE_POINT_FIVE), _CMP_GT_OQ); + __mmask16 cond_1_right_1 = _mm512_cmp_ps_mask(pos_x_i_vec_1, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE_POINT_FIVE), _CMP_GT_OQ); + + __mmask16 cond_1_0 = cond_1_left_0 & cond_1_right_0; + __mmask16 cond_1_1 = cond_1_left_1 & cond_1_right_1; + + pos_x_i_vec_0 = _mm512_mask_blend_ps(cond_1_0, pos_x_i_vec_0, _mm512_set1_ps(1.0f)); + pos_x_i_vec_1 = _mm512_mask_blend_ps(cond_1_1, pos_x_i_vec_1, _mm512_set1_ps(1.0f)); + + destination_y_i_vec_0 = _mm512_mask_blend_ps(cond_1_0, destination_y_i_vec_0, pos_y_i_vec_0); + destination_y_i_vec_1 = _mm512_mask_blend_ps(cond_1_1, destination_y_i_vec_1, pos_y_i_vec_1); + + w_x_i_vec_0 = _mm512_mask_blend_ps(cond_1_0, w_x_i_vec_0, desired_v0_i_vec_0); + w_x_i_vec_1 = _mm512_mask_blend_ps(cond_1_1, w_x_i_vec_1, desired_v0_i_vec_1); + + w_y_i_vec_0 = _mm512_mask_blend_ps(cond_1_0, w_y_i_vec_0, _mm512_setzero_ps()); + w_y_i_vec_1 = _mm512_mask_blend_ps(cond_1_1, w_y_i_vec_1, _mm512_setzero_ps()); + + curr_vel_x_i_vec_0 = _mm512_mask_blend_ps(cond_1_0, curr_vel_x_i_vec_0, w_x_i_vec_0); + curr_vel_x_i_vec_1 = _mm512_mask_blend_ps(cond_1_1, curr_vel_x_i_vec_1, w_x_i_vec_1); + + curr_vel_y_i_vec_0 = _mm512_mask_blend_ps(cond_1_0, curr_vel_y_i_vec_0, w_y_i_vec_0); + curr_vel_y_i_vec_1 = _mm512_mask_blend_ps(cond_1_1, curr_vel_y_i_vec_1, w_y_i_vec_1); + + __mmask16 cond_2_left_0 = _mm512_cmpeq_epi32_mask(color_i_vec_0, _mm512_set1_epi32(1)); + __mmask16 cond_2_left_1 = _mm512_cmpeq_epi32_mask(color_i_vec_1, _mm512_set1_epi32(1)); + + __mmask16 cond_2_right_0 = _mm512_cmp_ps_mask(pos_x_i_vec_0, _mm512_set1_ps(1.5f), _CMP_LT_OQ); + __mmask16 cond_2_right_1 = _mm512_cmp_ps_mask(pos_x_i_vec_1, _mm512_set1_ps(1.5f), _CMP_LT_OQ); + + __mmask16 cond_2_0 = cond_2_left_0 & cond_2_right_0; + __mmask16 cond_2_1 = cond_2_left_1 & cond_2_right_1; + + pos_x_i_vec_0 = _mm512_mask_blend_ps(cond_2_0, pos_x_i_vec_0, _mm512_set1_ps(BOARD_LENGTH - 1.0f)); + pos_x_i_vec_1 = _mm512_mask_blend_ps(cond_2_1, pos_x_i_vec_1, _mm512_set1_ps(BOARD_LENGTH - 1.0f)); + + destination_y_i_vec_0 = _mm512_mask_blend_ps(cond_2_0, destination_y_i_vec_0, pos_y_i_vec_0); + destination_y_i_vec_1 = _mm512_mask_blend_ps(cond_2_1, destination_y_i_vec_1, pos_y_i_vec_1); + + __m512 neg_desired_v0_0 = _mm512_xor_ps(desired_v0_i_vec_0, _mm512_set1_ps(-0.0f)); + __m512 neg_desired_v0_1 = _mm512_xor_ps(desired_v0_i_vec_1, _mm512_set1_ps(-0.0f)); + + w_x_i_vec_0 = _mm512_mask_blend_ps(cond_2_0, w_x_i_vec_0, neg_desired_v0_0); + w_x_i_vec_1 = _mm512_mask_blend_ps(cond_2_1, w_x_i_vec_1, neg_desired_v0_1); + + w_y_i_vec_0 = _mm512_mask_blend_ps(cond_2_0, w_y_i_vec_0, _mm512_setzero_ps()); + w_y_i_vec_1 = _mm512_mask_blend_ps(cond_2_1, w_y_i_vec_1, _mm512_setzero_ps()); + + curr_vel_x_i_vec_0 = _mm512_mask_blend_ps(cond_2_0, curr_vel_x_i_vec_0, w_x_i_vec_0); + curr_vel_y_i_vec_1 = _mm512_mask_blend_ps(cond_2_1, curr_vel_y_i_vec_1, w_y_i_vec_1); + + pos_y_i_vec_0 = _mm512_max_ps(pos_y_i_vec_0, _mm512_set1_ps(WALL_EPS)); + pos_y_i_vec_1 = _mm512_max_ps(pos_y_i_vec_1, _mm512_set1_ps(WALL_EPS)); + + pos_y_i_vec_0 = _mm512_min_ps(pos_y_i_vec_0, _mm512_set1_ps(BOARD_WIDTH_MINUS_WALL_EPS)); + pos_y_i_vec_1 = _mm512_min_ps(pos_y_i_vec_1, _mm512_set1_ps(BOARD_WIDTH_MINUS_WALL_EPS)); + + // # 32 ADDs + __m512 ex_vec_0 = _mm512_sub_ps(destination_x_i_vec_0, pos_x_i_vec_0); + __m512 ex_vec_1 = _mm512_sub_ps(destination_x_i_vec_1, pos_x_i_vec_1); + + // # 32 ADDs + __m512 ey_vec_0 = _mm512_sub_ps(destination_y_i_vec_0, pos_y_i_vec_0); + __m512 ey_vec_1 = _mm512_sub_ps(destination_y_i_vec_1, pos_y_i_vec_1); + + // # 64 MULTs, 32 ADDs + __m512 e_norm_sq_0 = _mm512_fmadd_ps(ex_vec_0, ex_vec_0, _mm512_mul_ps(ey_vec_0, ey_vec_0)); + __m512 e_norm_sq_1 = _mm512_fmadd_ps(ex_vec_1, ex_vec_1, _mm512_mul_ps(ey_vec_1, ey_vec_1)); + + // # 32 SQRTs + __m512 e_norm_0 = _mm512_sqrt_ps(e_norm_sq_0); + __m512 e_norm_1 = _mm512_sqrt_ps(e_norm_sq_1); + + // # 32 DIVs + __m512 e_norm_inv_0 = _mm512_div_ps(_mm512_set1_ps(1.0f), e_norm_0); + __m512 e_norm_inv_1 = _mm512_div_ps(_mm512_set1_ps(1.0f), e_norm_1); + + // # 32 MULTs + __m512 e_x_i_vec_0 = _mm512_mul_ps(ex_vec_0, e_norm_inv_0); + __m512 e_x_i_vec_1 = _mm512_mul_ps(ex_vec_1, e_norm_inv_1); + + // # 32 MULTs + __m512 e_y_i_vec_0 = _mm512_mul_ps(ey_vec_0, e_norm_inv_0); + __m512 e_y_i_vec_1 = _mm512_mul_ps(ey_vec_1, e_norm_inv_1); + + // # 64 MULTs, 32 ADDs + __m512 vel_norm_sq_0 = _mm512_fmadd_ps(curr_vel_x_i_vec_0, curr_vel_x_i_vec_0, _mm512_mul_ps(curr_vel_y_i_vec_0, curr_vel_y_i_vec_0)); + __m512 vel_norm_sq_1 = _mm512_fmadd_ps(curr_vel_x_i_vec_1, curr_vel_x_i_vec_1, _mm512_mul_ps(curr_vel_y_i_vec_1, curr_vel_y_i_vec_1)); + + // # 32 MULTs + __m512 sb_sq_i_vec_0 = _mm512_mul_ps(vel_norm_sq_0, _mm512_set1_ps(delta_t_sq)); + __m512 sb_sq_i_vec_1 = _mm512_mul_ps(vel_norm_sq_1, _mm512_set1_ps(delta_t_sq)); + + // # 32 SQRTs + __m512 vel_norm_dt_0 = _mm512_sqrt_ps(sb_sq_i_vec_0); + __m512 vel_norm_dt_1 = _mm512_sqrt_ps(sb_sq_i_vec_1); + + _mm512_storeu_ps(&curr_vel_x[i], curr_vel_x_i_vec_0); + _mm512_storeu_ps(&curr_vel_x[i + 16], curr_vel_x_i_vec_1); + + _mm512_storeu_ps(&curr_vel_y[i], curr_vel_y_i_vec_0); + _mm512_storeu_ps(&curr_vel_y[i + 16], curr_vel_y_i_vec_1); + + _mm512_storeu_ps(&w_x[i], w_x_i_vec_0); + _mm512_storeu_ps(&w_x[i + 16], w_x_i_vec_1); + + _mm512_storeu_ps(&w_y[i], w_y_i_vec_0); + _mm512_storeu_ps(&w_y[i + 16], w_y_i_vec_1); + + _mm512_storeu_ps(&pos_x[i], pos_x_i_vec_0); + _mm512_storeu_ps(&pos_x[i + 16], pos_x_i_vec_1); + + _mm512_storeu_ps(&pos_y[i], pos_y_i_vec_0); + _mm512_storeu_ps(&pos_y[i + 16], pos_y_i_vec_1); + + _mm512_storeu_ps(&e_x[i], e_x_i_vec_0); + _mm512_storeu_ps(&e_x[i + 16], e_x_i_vec_1); + + _mm512_storeu_ps(&e_y[i], e_y_i_vec_0); + _mm512_storeu_ps(&e_y[i + 16], e_y_i_vec_1); + + _mm512_storeu_ps(&destination_y[i], destination_y_i_vec_0); + _mm512_storeu_ps(&destination_y[i + 16], destination_y_i_vec_1); + + _mm512_storeu_ps(&sb_sq[i], sb_sq_i_vec_0); + _mm512_storeu_ps(&sb_sq[i + 16], sb_sq_i_vec_1); + + // # 32 MULTs + _mm512_storeu_ps(&sb_e_x[i], _mm512_mul_ps(e_x_i_vec_0, vel_norm_dt_0)); + _mm512_storeu_ps(&sb_e_x[i + 16], _mm512_mul_ps(e_x_i_vec_1, vel_norm_dt_1)); + + // # 32 MULTs + _mm512_storeu_ps(&sb_e_y[i], _mm512_mul_ps(e_y_i_vec_0, vel_norm_dt_0)); + _mm512_storeu_ps(&sb_e_y[i + 16], _mm512_mul_ps(e_y_i_vec_1, vel_norm_dt_1)); + } + +#if !BENCHMARK + for (int i = 0; i < n_p; i++) { + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix.cpp new file mode 100644 index 0000000..ec69800 --- /dev/null +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_expfix.cpp @@ -0,0 +1,634 @@ +// # Changes: Used _mm512_rsqrt14_ps() instead of _mm512_sqrt_ps() and _mm512_div_ps() +// # Predecessor: variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2.cpp + +#include "../headers/board_reduced_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_reduced_float.hpp" + +#include + +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0f +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 31) & ~31; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + float dest_x = BOARD_LENGTH + 30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + float dest_x = -30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9f; + pos_y[j] = 1e9f; + sb_sq[j] = 0.0f; + sb_e_x[j] = 0.0f; + sb_e_y[j] = 0.0f; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 256 MULTs, 224 ADDs +static inline __m512 _avx512_exp_ps(__m512 x) { + + const __m512 log2e = _mm512_set1_ps(1.4426950408889634f); + + // # 16 MULTs + __m512 nf = _mm512_roundscale_ps(_mm512_mul_ps(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + + const __m512 ln2 = _mm512_set1_ps(0.6931471805599453f); + + // # 16 MULTs, 16 ADDs + __m512 r = _mm512_fnmadd_ps(nf, ln2, x); + + const __m512 c13 = _mm512_set1_ps(c13_scalar); + const __m512 c12 = _mm512_set1_ps(c12_scalar); + const __m512 c11 = _mm512_set1_ps(c11_scalar); + const __m512 c10 = _mm512_set1_ps(c10_scalar); + const __m512 c9 = _mm512_set1_ps(c9_scalar); + const __m512 c8 = _mm512_set1_ps(c8_scalar); + const __m512 c7 = _mm512_set1_ps(c7_scalar); + const __m512 c6 = _mm512_set1_ps(c6_scalar); + const __m512 c5 = _mm512_set1_ps(c5_scalar); + const __m512 c4 = _mm512_set1_ps(c4_scalar); + const __m512 c3 = _mm512_set1_ps(c3_scalar); + const __m512 c2 = _mm512_set1_ps(c2_scalar); + const __m512 c1 = _mm512_set1_ps(c1_scalar); + const __m512 c0 = _mm512_set1_ps(c0_scalar); + + __m512 p = c13; + + // # 13 * (16 MULTs, 16 ADDs) + // # = 208 MULTs, 208 ADDs + p = _mm512_fmadd_ps(p, r, c12); + p = _mm512_fmadd_ps(p, r, c11); + p = _mm512_fmadd_ps(p, r, c10); + p = _mm512_fmadd_ps(p, r, c9); + p = _mm512_fmadd_ps(p, r, c8); + p = _mm512_fmadd_ps(p, r, c7); + p = _mm512_fmadd_ps(p, r, c6); + p = _mm512_fmadd_ps(p, r, c5); + p = _mm512_fmadd_ps(p, r, c4); + p = _mm512_fmadd_ps(p, r, c3); + p = _mm512_fmadd_ps(p, r, c2); + p = _mm512_fmadd_ps(p, r, c1); + p = _mm512_fmadd_ps(p, r, c0); + + __m512i ni = _mm512_cvtps_epi32(nf); + __m512i biased = _mm512_add_epi32(ni, _mm512_set1_epi32(127)); + __m512i scaled = _mm512_slli_epi32(biased, 23); + __m512 pow2n = _mm512_castsi512_ps(scaled); + + // # 16 MULTs + return _mm512_mul_ps(p, pow2n); +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + (void)pedestrians; +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 31) & ~31; + + alignas(64) const float lane_offset_arr[16] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f}; + const __m512 lane_off = _mm512_load_ps(lane_offset_arr); + + const __m512 v_neg_v0_div_2s = _mm512_set1_ps(NEG_V0_AB_div_TWO_SIGMA); + const __m512 v_neg_2s_inv = _mm512_set1_ps(NEG_TWO_SIGMA_INV); + const __m512 v_cos_phi_sq = _mm512_set1_ps(cos_phi_sq); + const __m512 v_dt_neg = _mm512_set1_ps(dt_neg); + const __m512 v_c_neg_dt = _mm512_set1_ps(c_neg_times_dt); + const __m512 v_zero = _mm512_setzero_ps(); + const __m512 v_one = _mm512_set1_ps(1.0f); + const __m512 v_eps = _mm512_set1_ps(EPS); + const __m512 v_eps_sq = _mm512_set1_ps(EPS_SQ); + const __m512 v_np = _mm512_set1_ps((float)n_p); + const __m512 v_exp_min = _mm512_set1_ps(-87.0f); + + // # ADDs: n_iter * ( + // # n_p * 68 + + // # n_p * n_p_pad * 29 + // # n_p * board.n_obstacles * 10 + // # n_p_pad * 9 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + + // # n_p * n_p_pad * 40 + // # n_p * board.n_obstacles * 13 + // # n_p_pad * 17 + // # ) + + // # DIVs: n_iter * ( + // # n_p * n_p_pad + // # n_p * board.n_obstacles + // # n_p_pad * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * n_p_pad * 3 + // # n_p * board.n_obstacles + // # n_p_pad * 3 + // # ) + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + + // # 2 MULTs + float desired_velocity_x = e_x[i] * desired_v0[i]; + float desired_velocity_y = e_y[i] * desired_v0[i]; + + // # 2 ADDs, 2 MULTs + float f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; + float f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; + + const __m512 pix = _mm512_set1_ps(pos_x[i]); + const __m512 piy = _mm512_set1_ps(pos_y[i]); + const __m512 eix = _mm512_set1_ps(e_x[i]); + const __m512 eiy = _mm512_set1_ps(e_y[i]); + const __m512 v_i = _mm512_set1_ps((float)i); + + __m512 acc_x_0 = _mm512_setzero_ps(); + __m512 acc_y_0 = _mm512_setzero_ps(); + __m512 acc_x_1 = _mm512_setzero_ps(); + __m512 acc_y_1 = _mm512_setzero_ps(); + + for (int j = 0; j < n_p_pad; j += 32) { + + // # 32 ADDs + __m512 j_idx_0 = _mm512_add_ps(_mm512_set1_ps((float)j), lane_off); + __m512 j_idx_1 = _mm512_add_ps(_mm512_set1_ps((float)j + 16), lane_off); + + __mmask16 m_neq_i_0 = _mm512_cmp_ps_mask(j_idx_0, v_i, _CMP_NEQ_OQ); + __mmask16 m_neq_i_1 = _mm512_cmp_ps_mask(j_idx_1, v_i, _CMP_NEQ_OQ); + + __mmask16 m_in_range_0 = _mm512_cmp_ps_mask(j_idx_0, v_np, _CMP_LT_OQ); + __mmask16 m_in_range_1 = _mm512_cmp_ps_mask(j_idx_1, v_np, _CMP_LT_OQ); + + __mmask16 active_0 = m_neq_i_0 & m_in_range_0; + __mmask16 active_1 = m_neq_i_1 & m_in_range_1; + + __m512 pjx_0 = _mm512_loadu_ps(&pos_x[j]); + __m512 pjx_1 = _mm512_loadu_ps(&pos_x[j + 16]); + + __m512 pjy_0 = _mm512_loadu_ps(&pos_y[j]); + __m512 pjy_1 = _mm512_loadu_ps(&pos_y[j + 16]); + + __m512 sbe_jx_0 = _mm512_loadu_ps(&sb_e_x[j]); + __m512 sbe_jx_1 = _mm512_loadu_ps(&sb_e_x[j + 16]); + + __m512 sbe_jy_0 = _mm512_loadu_ps(&sb_e_y[j]); + __m512 sbe_jy_1 = _mm512_loadu_ps(&sb_e_y[j + 16]); + + __m512 sb_jsq_0 = _mm512_loadu_ps(&sb_sq[j]); + __m512 sb_jsq_1 = _mm512_loadu_ps(&sb_sq[j + 16]); + + // # 32 ADDs + __m512 r_ab_x_0 = _mm512_sub_ps(pix, pjx_0); + __m512 r_ab_x_1 = _mm512_sub_ps(pix, pjx_1); + + // # 32 ADDs + __m512 r_ab_y_0 = _mm512_sub_ps(piy, pjy_0); + __m512 r_ab_y_1 = _mm512_sub_ps(piy, pjy_1); + + // # 64 MULTs, 32 ADDs + __m512 r_ab_n2_0 = _mm512_fmadd_ps(r_ab_x_0, r_ab_x_0, _mm512_mul_ps(r_ab_y_0, r_ab_y_0)); + __m512 r_ab_n2_1 = _mm512_fmadd_ps(r_ab_x_1, r_ab_x_1, _mm512_mul_ps(r_ab_y_1, r_ab_y_1)); + + // # 32 SQRTs + __m512 r_ab_n_0 = _mm512_sqrt_ps(r_ab_n2_0); + __m512 r_ab_n_1 = _mm512_sqrt_ps(r_ab_n2_1); + + // # 32 ADDs + __m512 r_ab2_x_0 = _mm512_sub_ps(r_ab_x_0, sbe_jx_0); + __m512 r_ab2_x_1 = _mm512_sub_ps(r_ab_x_1, sbe_jx_1); + + // # 32 ADDs + __m512 r_ab2_y_0 = _mm512_sub_ps(r_ab_y_0, sbe_jy_0); + __m512 r_ab2_y_1 = _mm512_sub_ps(r_ab_y_1, sbe_jy_1); + + // # 64 MULTs, 32 ADDs + __m512 r_ab2_n2_0 = _mm512_fmadd_ps(r_ab2_x_0, r_ab2_x_0, _mm512_mul_ps(r_ab2_y_0, r_ab2_y_0)); + __m512 r_ab2_n2_1 = _mm512_fmadd_ps(r_ab2_x_1, r_ab2_x_1, _mm512_mul_ps(r_ab2_y_1, r_ab2_y_1)); + + // # 32 SQRTs + __m512 r_ab2_n_0 = _mm512_sqrt_ps(r_ab2_n2_0); + __m512 r_ab2_n_1 = _mm512_sqrt_ps(r_ab2_n2_1); + + // # 32 ADDs + __m512 r_sum_0 = _mm512_add_ps(r_ab_n_0, r_ab2_n_0); + __m512 r_sum_1 = _mm512_add_ps(r_ab_n_1, r_ab2_n_1); + + // # 32 MULTs, 32 ADDs + __m512 two_b_sq_0 = _mm512_fmsub_ps(r_sum_0, r_sum_0, sb_jsq_0); + __m512 two_b_sq_1 = _mm512_fmsub_ps(r_sum_1, r_sum_1, sb_jsq_1); + + // # 32 SQRTs + __m512 two_b_0 = _mm512_sqrt_ps(two_b_sq_0); + __m512 two_b_1 = _mm512_sqrt_ps(two_b_sq_1); + + // # 32 MULTs + __m512 e_arg_0 = _mm512_mul_ps(two_b_0, v_neg_2s_inv); + __m512 e_arg_1 = _mm512_mul_ps(two_b_1, v_neg_2s_inv); + + e_arg_0 = _mm512_max_ps(e_arg_0, v_exp_min); + e_arg_1 = _mm512_max_ps(e_arg_1, v_exp_min); + + // # 512 MULTs, 448 ADDs + __m512 e_val_0 = _avx512_exp_ps(e_arg_0); + __m512 e_val_1 = _avx512_exp_ps(e_arg_1); + + // # 64 MULTs + __m512 numer_0 = _mm512_mul_ps(_mm512_mul_ps(r_sum_0, v_neg_v0_div_2s), e_val_0); + __m512 numer_1 = _mm512_mul_ps(_mm512_mul_ps(r_sum_1, v_neg_v0_div_2s), e_val_1); + + // # 64 MULTs + __m512 denom_0 = _mm512_mul_ps(_mm512_mul_ps(two_b_0, r_ab_n_0), r_ab2_n_0); + __m512 denom_1 = _mm512_mul_ps(_mm512_mul_ps(two_b_1, r_ab_n_1), r_ab2_n_1); + + __m512 denom_safe_0 = _mm512_mask_blend_ps(active_0, v_one, denom_0); + __m512 denom_safe_1 = _mm512_mask_blend_ps(active_1, v_one, denom_1); + + // # 32 DIVs + __m512 smc_0 = _mm512_div_ps(numer_0, denom_safe_0); + __m512 smc_1 = _mm512_div_ps(numer_1, denom_safe_1); + + // # 32 MULTs + __m512 sm_r_ab_0 = _mm512_mul_ps(smc_0, r_ab2_n_0); + __m512 sm_r_ab_1 = _mm512_mul_ps(smc_1, r_ab2_n_1); + + // # 32 MULTs + __m512 sm_r_ab2_0 = _mm512_mul_ps(smc_0, r_ab_n_0); + __m512 sm_r_ab2_1 = _mm512_mul_ps(smc_1, r_ab_n_1); + + // # 64 MULTs, 32 ADDs + __m512 f_x_0 = _mm512_fmadd_ps(r_ab2_x_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_x_0, sm_r_ab_0)); + __m512 f_x_1 = _mm512_fmadd_ps(r_ab2_x_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_x_1, sm_r_ab_1)); + + // # 64 MULTs, 32 ADDs + __m512 f_y_0 = _mm512_fmadd_ps(r_ab2_y_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_y_0, sm_r_ab_0)); + __m512 f_y_1 = _mm512_fmadd_ps(r_ab2_y_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_y_1, sm_r_ab_1)); + + // # 64 MULTs, 32 ADDs + __m512 f_norm_sq_0 = _mm512_fmadd_ps(f_x_0, f_x_0, _mm512_mul_ps(f_y_0, f_y_0)); + __m512 f_norm_sq_1 = _mm512_fmadd_ps(f_x_1, f_x_1, _mm512_mul_ps(f_y_1, f_y_1)); + + // # 32 MULTs + __m512 rhs_0 = _mm512_mul_ps(f_norm_sq_0, v_cos_phi_sq); + __m512 rhs_1 = _mm512_mul_ps(f_norm_sq_1, v_cos_phi_sq); + + // # 64 MULTs, 32 ADDs + __m512 e_dot_f_0 = _mm512_fmadd_ps(eix, f_x_0, _mm512_mul_ps(eiy, f_y_0)); + __m512 e_dot_f_1 = _mm512_fmadd_ps(eix, f_x_1, _mm512_mul_ps(eiy, f_y_1)); + + // # 32 MULTs + __m512 e_dot_f_sq_0 = _mm512_mul_ps(e_dot_f_0, e_dot_f_0); + __m512 e_dot_f_sq_1 = _mm512_mul_ps(e_dot_f_1, e_dot_f_1); + + __mmask16 c1_0 = _mm512_cmp_ps_mask(e_dot_f_0, v_zero, _CMP_LT_OQ); + __mmask16 c1_1 = _mm512_cmp_ps_mask(e_dot_f_1, v_zero, _CMP_LT_OQ); + + __mmask16 c2_0 = _mm512_cmp_ps_mask(e_dot_f_sq_0, rhs_0, _CMP_GT_OQ); + __mmask16 c2_1 = _mm512_cmp_ps_mask(e_dot_f_sq_1, rhs_1, _CMP_GT_OQ); + + __mmask16 cond_0 = c1_0 & c2_0; + __mmask16 cond_1 = c1_1 & c2_1; + + __m512 w_val_0 = _mm512_mask_blend_ps(cond_0, v_dt_neg, v_c_neg_dt); + __m512 w_val_1 = _mm512_mask_blend_ps(cond_1, v_dt_neg, v_c_neg_dt); + + __m512 f_x_safe_0 = _mm512_maskz_mov_ps(active_0, f_x_0); + __m512 f_x_safe_1 = _mm512_maskz_mov_ps(active_1, f_x_1); + + __m512 f_y_safe_0 = _mm512_maskz_mov_ps(active_0, f_y_0); + __m512 f_y_safe_1 = _mm512_maskz_mov_ps(active_1, f_y_1); + + // # 32 MULTs, 32 ADDs + acc_x_0 = _mm512_fmadd_ps(f_x_safe_0, w_val_0, acc_x_0); + acc_x_1 = _mm512_fmadd_ps(f_x_safe_1, w_val_1, acc_x_1); + + // # 32 MULTs, 32 ADDs + acc_y_0 = _mm512_fmadd_ps(f_y_safe_0, w_val_0, acc_y_0); + acc_y_1 = _mm512_fmadd_ps(f_y_safe_1, w_val_1, acc_y_1); + } + + // # 64 ADDs + f_alpha_dt_x += _mm512_reduce_add_ps(_mm512_add_ps(acc_x_0, acc_x_1)); + f_alpha_dt_y += _mm512_reduce_add_ps(_mm512_add_ps(acc_y_0, acc_y_1)); + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + float v1_x = pos_x[i] - board.obstacles[k].start_x; + float v1_y = pos_y[i] - board.obstacles[k].start_y; + float v2_x = board.obstacles[k].obstacle_v_x; + float v2_y = board.obstacles[k].obstacle_v_y; + + // # 3 MULTs, 1 ADD + float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0f) + projection = 0.0f; + else if (projection > 1.0f) + projection = 1.0f; + + // # 4 ADDs, 2 MULTs + float r_aB_x = pos_x[i] - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + float r_aB_y = pos_y[i] - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; + + // # 4 MULTs, 1 EXP, 1 DIV + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + float f_alpha_B_neg_x = r_aB_x * scalar_mult; + float f_alpha_B_neg_y = r_aB_y * scalar_mult; + + float w_val = dt_neg; + float e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y[i] : e_y[i]); + + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTS + float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p_pad; i += 16) { + + __m512 w_x_i_vec = _mm512_loadu_ps(&w_x[i]); + __m512 w_y_i_vec = _mm512_loadu_ps(&w_y[i]); + __m512 v_max_i_vec = _mm512_loadu_ps(&v_max[i]); + __m512 pos_x_i_vec = _mm512_loadu_ps(&pos_x[i]); + __m512 pos_y_i_vec = _mm512_loadu_ps(&pos_y[i]); + __m512 destination_y_i_vec = _mm512_loadu_ps(&destination_y[i]); + __m512 destination_x_i_vec = _mm512_loadu_ps(&destination_x[i]); + __m512 desired_v0_i_vec = _mm512_loadu_ps(&desired_v0[i]); + + __m512i color_i_vec = _mm512_loadu_si512((__m512i *)&color[i]); + + // # 32 MULTs, 16 ADDs + __m512 w_norm_sq = _mm512_fmadd_ps(w_x_i_vec, w_x_i_vec, _mm512_mul_ps(w_y_i_vec, w_y_i_vec)); + + // # 16 SQRTs, 16 DIVs + __m512 w_norm_inv = _mm512_rsqrt14_ps(w_norm_sq); + + // # 16 MULTs + __m512 correction_factor = _mm512_min_ps(_mm512_set1_ps(1.0f), _mm512_mul_ps(v_max_i_vec, w_norm_inv)); + + // # 32 MULTs + __m512 curr_vel_x_i_vec = _mm512_mul_ps(w_x_i_vec, correction_factor); + __m512 curr_vel_y_i_vec = _mm512_mul_ps(w_y_i_vec, correction_factor); + + __m512 dt_vec = _mm512_set1_ps(dt); + + // # 32 MULTs, 32 ADDs + pos_x_i_vec = _mm512_fmadd_ps(curr_vel_x_i_vec, dt_vec, pos_x_i_vec); + pos_y_i_vec = _mm512_fmadd_ps(curr_vel_y_i_vec, dt_vec, pos_y_i_vec); + + __mmask16 cond_1_left = _mm512_cmpeq_epi32_mask(color_i_vec, _mm512_setzero_si512()); + __mmask16 cond_1_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE_POINT_FIVE), _CMP_GT_OQ); + __mmask16 cond_1 = cond_1_left & cond_1_right; + + pos_x_i_vec = _mm512_mask_blend_ps(cond_1, pos_x_i_vec, _mm512_set1_ps(1.0f)); + destination_y_i_vec = _mm512_mask_blend_ps(cond_1, destination_y_i_vec, pos_y_i_vec); + w_x_i_vec = _mm512_mask_blend_ps(cond_1, w_x_i_vec, desired_v0_i_vec); + w_y_i_vec = _mm512_mask_blend_ps(cond_1, w_y_i_vec, _mm512_setzero_ps()); + curr_vel_x_i_vec = _mm512_mask_blend_ps(cond_1, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_ps(cond_1, curr_vel_y_i_vec, w_y_i_vec); + + __mmask16 cond_2_left = _mm512_cmpeq_epi32_mask(color_i_vec, _mm512_set1_epi32(1)); + __mmask16 cond_2_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(1.5f), _CMP_LT_OQ); + __mmask16 cond_2 = cond_2_left & cond_2_right; + + pos_x_i_vec = _mm512_mask_blend_ps(cond_2, pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE)); + destination_y_i_vec = _mm512_mask_blend_ps(cond_2, destination_y_i_vec, pos_y_i_vec); + __m512 neg_desired_v0 = _mm512_xor_ps(desired_v0_i_vec, _mm512_set1_ps(-0.0f)); + w_x_i_vec = _mm512_mask_blend_ps(cond_2, w_x_i_vec, neg_desired_v0); + w_y_i_vec = _mm512_mask_blend_ps(cond_2, w_y_i_vec, _mm512_setzero_ps()); + curr_vel_x_i_vec = _mm512_mask_blend_ps(cond_2, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_ps(cond_2, curr_vel_y_i_vec, w_y_i_vec); + + pos_y_i_vec = _mm512_max_ps(pos_y_i_vec, _mm512_set1_ps(WALL_EPS)); + pos_y_i_vec = _mm512_min_ps(pos_y_i_vec, _mm512_set1_ps(BOARD_WIDTH_MINUS_WALL_EPS)); + + // # 32 ADDs + __m512 ex_vec = _mm512_sub_ps(destination_x_i_vec, pos_x_i_vec); + __m512 ey_vec = _mm512_sub_ps(destination_y_i_vec, pos_y_i_vec); + + // # 32 MULTs, 16 ADDs + __m512 e_norm_sq = _mm512_fmadd_ps(ex_vec, ex_vec, _mm512_mul_ps(ey_vec, ey_vec)); + + // # 16 DIVs, 16 SQRTs + __m512 e_norm_inv = _mm512_rsqrt14_ps(e_norm_sq); + + // # 32 MULTs + __m512 e_x_i_vec = _mm512_mul_ps(ex_vec, e_norm_inv); + __m512 e_y_i_vec = _mm512_mul_ps(ey_vec, e_norm_inv); + + // # 32 MULTs, 16 ADDs + __m512 vel_norm_sq = _mm512_fmadd_ps(curr_vel_x_i_vec, curr_vel_x_i_vec, _mm512_mul_ps(curr_vel_y_i_vec, curr_vel_y_i_vec)); + + // # 16 MULTs + __m512 sb_sq_i_vec = _mm512_mul_ps(vel_norm_sq, _mm512_set1_ps(delta_t_sq)); + + // # 16 SQRTs + __m512 vel_norm_dt = _mm512_sqrt_ps(sb_sq_i_vec); + + _mm512_storeu_ps(&curr_vel_x[i], curr_vel_x_i_vec); + _mm512_storeu_ps(&curr_vel_y[i], curr_vel_y_i_vec); + _mm512_storeu_ps(&w_x[i], w_x_i_vec); + _mm512_storeu_ps(&w_y[i], w_y_i_vec); + _mm512_storeu_ps(&pos_x[i], pos_x_i_vec); + _mm512_storeu_ps(&pos_y[i], pos_y_i_vec); + _mm512_storeu_ps(&e_x[i], e_x_i_vec); + _mm512_storeu_ps(&e_y[i], e_y_i_vec); + _mm512_storeu_ps(&destination_y[i], destination_y_i_vec); + _mm512_storeu_ps(&sb_sq[i], sb_sq_i_vec); + + // # 32 MULTs + _mm512_storeu_ps(&sb_e_x[i], _mm512_mul_ps(e_x_i_vec, vel_norm_dt)); + _mm512_storeu_ps(&sb_e_y[i], _mm512_mul_ps(e_y_i_vec, vel_norm_dt)); + } + +#if !BENCHMARK + for (int i = 0; i < n_p; i++) { + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix.cpp index d682289..a9bbd5c 100644 --- a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix.cpp +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix.cpp @@ -1,5 +1,5 @@ -// # Changes: Replaced sqrt_ps with rsqrt14_ps in the pedestrian loop, similar to @lbaumberger in variant_float_inlining_SoA_AVX2_polyexp_rsqrt.cpp -// # Predecessor: variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt.cpp +// # Changes: Added more correction rounds to _avx512_exp_ps to do 30 flops per scalar +// # Predecessor: variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt.cpp #include "../headers/board_reduced_float.hpp" #include "../headers/constants_float.hpp" @@ -13,6 +13,8 @@ #define SEED 42 #define BOARD_WIDTH 10.0f #define BOARD_LENGTH 50.0f +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0f +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5f #define WALL_EPS 1e-3f #define BOARD_WIDTH_MINUS_WALL_EPS 9.999f @@ -160,19 +162,20 @@ Pedestrian *init_pedestrians(int n_p) { Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } +// # 256 MULTs, 224 ADDs static inline __m512 _avx512_exp_ps(__m512 x) { - // define own inlined intrinsic function for approximating the exponent function - // e^x = 2^n * e^r --> x = n * ln(2) + r const __m512 log2e = _mm512_set1_ps(1.4426950408889634f); + + // # 16 MULTs __m512 nf = _mm512_roundscale_ps(_mm512_mul_ps(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); const __m512 ln2 = _mm512_set1_ps(0.6931471805599453f); - // r = x - n * ln(2) + + // # 16 MULTs, 16 ADDs __m512 r = _mm512_fnmadd_ps(nf, ln2, x); - // approximation of e^r using taylor polynomial - // cNUM --> coefficients + const __m512 c13 = _mm512_set1_ps(c13_scalar); const __m512 c12 = _mm512_set1_ps(c12_scalar); const __m512 c11 = _mm512_set1_ps(c11_scalar); const __m512 c10 = _mm512_set1_ps(c10_scalar); @@ -187,8 +190,10 @@ static inline __m512 _avx512_exp_ps(__m512 x) { const __m512 c1 = _mm512_set1_ps(c1_scalar); const __m512 c0 = _mm512_set1_ps(c0_scalar); - // apply coefficients - __m512 p = c12; + __m512 p = c13; + + // # 13 * (16 MULTs, 16 ADDs) + // # = 208 MULTs, 208 ADDs p = _mm512_fmadd_ps(p, r, c12); p = _mm512_fmadd_ps(p, r, c11); p = _mm512_fmadd_ps(p, r, c10); @@ -203,13 +208,12 @@ static inline __m512 _avx512_exp_ps(__m512 x) { p = _mm512_fmadd_ps(p, r, c1); p = _mm512_fmadd_ps(p, r, c0); - // use bit shifting for 2^n and bias because float have 23 bit mantissa __m512i ni = _mm512_cvtps_epi32(nf); __m512i biased = _mm512_add_epi32(ni, _mm512_set1_epi32(127)); __m512i scaled = _mm512_slli_epi32(biased, 23); __m512 pow2n = _mm512_castsi512_ps(scaled); - // e^x + // # 16 MULTs return _mm512_mul_ps(p, pow2n); } @@ -248,254 +252,227 @@ int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, c const __m512 v_np = _mm512_set1_ps((float)n_p); const __m512 v_exp_min = _mm512_set1_ps(-87.0f); + // # ADDs: n_iter * ( + // # n_p * 68 + + // # n_p * n_p_pad * 29 + + // # n_p * board.n_obstacles * 10 + + // # n_p_pad * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + + // # n_p * n_p_pad * 42 + + // # n_p * board.n_obstacles * 13 + + // # n_p_pad * 16 + // # ) + + // # DIVs: n_iter * ( + // # n_p * n_p_pad * 3 + + // # n_p * board.n_obstacles + + // # n_p_pad * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * n_p_pad * 3 + + // # n_p * board.n_obstacles + + // # n_p_pad * 3 + // # ) + + // # EXPs: n_iter * n_p * board.n_obstacles + for (int t = 0; t < n_iter; t++) { for (int i = 0; i < n_p; i++) { - // set the vector for the current pedestrian - // get desired velocity + // # 2 MULTs float desired_velocity_x = e_x[i] * desired_v0[i]; float desired_velocity_y = e_y[i] * desired_v0[i]; - // velocity change accumulator + // # 2 ADDs, 2 MULTs float f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; float f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; - // pos const __m512 pix = _mm512_set1_ps(pos_x[i]); const __m512 piy = _mm512_set1_ps(pos_y[i]); - // desired direction const __m512 eix = _mm512_set1_ps(e_x[i]); const __m512 eiy = _mm512_set1_ps(e_y[i]); - // broadcast index used by mask to prevent situation pedestrian[i] == pedestrian[j], see m_neq_i_0 and m_neq_i_1 const __m512 v_i = _mm512_set1_ps((float)i); - // accumulators --> 16 pedestrians per accumulator __m512 acc_x_0 = _mm512_setzero_ps(); __m512 acc_y_0 = _mm512_setzero_ps(); __m512 acc_x_1 = _mm512_setzero_ps(); __m512 acc_y_1 = _mm512_setzero_ps(); - // force between pedestrians - // loop unroll factor 32 with 2 vectors - // --> each vector has 16 lanes for (int j = 0; j < n_p_pad; j += 32) { - // [j, j+1, j+2, ..., j+15] and [j+16, j+17, j+18, ..., j+31] + // # 32 ADDs __m512 j_idx_0 = _mm512_add_ps(_mm512_set1_ps((float)j), lane_off); __m512 j_idx_1 = _mm512_add_ps(_mm512_set1_ps((float)j + 16), lane_off); - // lane is active if j != i - // [1,1,1,0,1,1,1,...] 0 --> i == j, 1 --> i != j __mmask16 m_neq_i_0 = _mm512_cmp_ps_mask(j_idx_0, v_i, _CMP_NEQ_OQ); __mmask16 m_neq_i_1 = _mm512_cmp_ps_mask(j_idx_1, v_i, _CMP_NEQ_OQ); - // lane is active if j < n_p --> valid range - // [1,1,1,0,1,1,1,...] 0 --> j >= n_p, 1 --> j < n_p __mmask16 m_in_range_0 = _mm512_cmp_ps_mask(j_idx_0, v_np, _CMP_LT_OQ); __mmask16 m_in_range_1 = _mm512_cmp_ps_mask(j_idx_1, v_np, _CMP_LT_OQ); - // bitwise comparison if not valid --> 0 - // finally check if lane is valid or not --> prevents i == j, and - // j >= n_p because of loop unrolling --> we can therefore omit a remainings for loop __mmask16 active_0 = m_neq_i_0 & m_in_range_0; __mmask16 active_1 = m_neq_i_1 & m_in_range_1; - // --- - - // load the positions of the other pedestrians x value - // [pos[j], pos[j+1], ..., pos[j+15]] and [pos[16], pos[j+17], ..., pos[j+31]] for x and y __m512 pjx_0 = _mm512_loadu_ps(&pos_x[j]); __m512 pjx_1 = _mm512_loadu_ps(&pos_x[j + 16]); __m512 pjy_0 = _mm512_loadu_ps(&pos_y[j]); __m512 pjy_1 = _mm512_loadu_ps(&pos_y[j + 16]); - // --- - - // step vector of j - // [(v_j * delta_t * e_j).x, (v_j+1 * delta_t * e_j+1).x, ...] __m512 sbe_jx_0 = _mm512_loadu_ps(&sb_e_x[j]); __m512 sbe_jx_1 = _mm512_loadu_ps(&sb_e_x[j + 16]); __m512 sbe_jy_0 = _mm512_loadu_ps(&sb_e_y[j]); __m512 sbe_jy_1 = _mm512_loadu_ps(&sb_e_y[j + 16]); - // --- - - // squared step length - // [j, j+1, ...] __m512 sb_jsq_0 = _mm512_loadu_ps(&sb_sq[j]); __m512 sb_jsq_1 = _mm512_loadu_ps(&sb_sq[j + 16]); - // --- - - // distance vector - // [j, j+1, ...] + // # 64 ADDs __m512 r_ab_x_0 = _mm512_sub_ps(pix, pjx_0); __m512 r_ab_x_1 = _mm512_sub_ps(pix, pjx_1); __m512 r_ab_y_0 = _mm512_sub_ps(piy, pjy_0); __m512 r_ab_y_1 = _mm512_sub_ps(piy, pjy_1); - // |r_ab|^2 needed for rsqrt to prevent 0 values --> x^2 + y^2 + // # 64 MULTs, 32 ADDs __m512 r_ab_n2_0 = _mm512_fmadd_ps(r_ab_x_0, r_ab_x_0, _mm512_mul_ps(r_ab_y_0, r_ab_y_0)); __m512 r_ab_n2_1 = _mm512_fmadd_ps(r_ab_x_1, r_ab_x_1, _mm512_mul_ps(r_ab_y_1, r_ab_y_1)); - // prevent cases where distance = 0 (=pedestrian on top of each other) - // [dist_i_j, dist_i_j+1, ...] r_ab_n2_0 = _mm512_max_ps(r_ab_n2_0, v_eps_sq); r_ab_n2_1 = _mm512_max_ps(r_ab_n2_1, v_eps_sq); - // --- - - // 1 / |r_ab| --> 14 bit rsqrt approx. rsqrt --> 1 / x^2 --> rsqrt(x^2) = 1/x - // [1 / dist_i_j, 1 / dist_i_j+1, ...] + // # 32 DIVs, 32 SQRTs __m512 inv_r_ab_n_0 = _mm512_rsqrt14_ps(r_ab_n2_0); __m512 inv_r_ab_n_1 = _mm512_rsqrt14_ps(r_ab_n2_1); - // r_ab^2 * 1 / r_ab = |r_ab| --> normed - // [r_i_j, r_i_j+1, ...] + // # 32 MULTs __m512 r_ab_n_0 = _mm512_mul_ps(r_ab_n2_0, inv_r_ab_n_0); __m512 r_ab_n_1 = _mm512_mul_ps(r_ab_n2_1, inv_r_ab_n_1); - // r_ab - step[j] - // j next pos + // # 64 ADDs __m512 r_ab2_x_0 = _mm512_sub_ps(r_ab_x_0, sbe_jx_0); __m512 r_ab2_x_1 = _mm512_sub_ps(r_ab_x_1, sbe_jx_1); __m512 r_ab2_y_0 = _mm512_sub_ps(r_ab_y_0, sbe_jy_0); __m512 r_ab2_y_1 = _mm512_sub_ps(r_ab_y_1, sbe_jy_1); - // |r_ab_2| --> needed for rsqrt trick (r_ab - step) + // # 64 MULTs, 32 ADDs __m512 r_ab2_n2_0 = _mm512_fmadd_ps(r_ab2_x_0, r_ab2_x_0, _mm512_mul_ps(r_ab2_y_0, r_ab2_y_0)); __m512 r_ab2_n2_1 = _mm512_fmadd_ps(r_ab2_x_1, r_ab2_x_1, _mm512_mul_ps(r_ab2_y_1, r_ab2_y_1)); - // prevent 0 case --> infinity r_ab2_n2_0 = _mm512_max_ps(r_ab2_n2_0, v_eps_sq); r_ab2_n2_1 = _mm512_max_ps(r_ab2_n2_1, v_eps_sq); - // same as before use rsqrt with 14bit approx - // [1 / |r_ab_2|, 1 / |r_ab_2|, ...] + // # 32 DIVs, 32 SQRTs __m512 inv_r_ab2_n_0 = _mm512_rsqrt14_ps(r_ab2_n2_0); __m512 inv_r_ab2_n_1 = _mm512_rsqrt14_ps(r_ab2_n2_1); - // |r_ab_2_second_distance_vector| * 1 / |r_ab_2_first_distance_vector| + // # 32 MULTs __m512 r_ab2_n_0 = _mm512_mul_ps(r_ab2_n2_0, inv_r_ab2_n_0); __m512 r_ab2_n_1 = _mm512_mul_ps(r_ab2_n2_1, inv_r_ab2_n_1); - // r_sum = |r_ab| + |r_ab - step[j]| --> [w_0, w_1, w_2, ..., w_15] and [w_16, ..., w_31] + // # 32 ADDs __m512 r_sum_0 = _mm512_add_ps(r_ab_n_0, r_ab2_n_0); __m512 r_sum_1 = _mm512_add_ps(r_ab_n_1, r_ab2_n_1); - // 2_b^2 = r_sum^2 - step[j]^2 + // # 32 MULTs, 32 ADDs __m512 two_b_sq_0 = _mm512_fmsub_ps(r_sum_0, r_sum_0, sb_jsq_0); __m512 two_b_sq_1 = _mm512_fmsub_ps(r_sum_1, r_sum_1, sb_jsq_1); - // prevent 0 case two_b_sq_0 = _mm512_max_ps(two_b_sq_0, v_eps_sq); two_b_sq_1 = _mm512_max_ps(two_b_sq_1, v_eps_sq); - // 2_b - // 1 / 2_b^(2*0.5) --> 1 / 2_b + // # 32 DIVs, 32 SQRTs __m512 inv_two_b_0 = _mm512_rsqrt14_ps(two_b_sq_0); __m512 inv_two_b_1 = _mm512_rsqrt14_ps(two_b_sq_1); - // 2_b = 2_b^2 * 1 / 2_b + // # 32 MULTs __m512 two_b_0 = _mm512_mul_ps(two_b_sq_0, inv_two_b_0); __m512 two_b_1 = _mm512_mul_ps(two_b_sq_1, inv_two_b_1); - // --- - - // two_b * -1 / (2*sigma) --> exp + // # 32 MULTs __m512 e_arg_0 = _mm512_mul_ps(two_b_0, v_neg_2s_inv); __m512 e_arg_1 = _mm512_mul_ps(two_b_1, v_neg_2s_inv); - // exp(x) - // when x is small just assume constant value --> faster exp e_arg_0 = _mm512_max_ps(e_arg_0, v_exp_min); e_arg_1 = _mm512_max_ps(e_arg_1, v_exp_min); - // custom fast exponent intrinsic using polynomial approximations and some precomputed constants + // # 512 MULTs, 448 ADDs __m512 e_val_0 = _avx512_exp_ps(e_arg_0); __m512 e_val_1 = _avx512_exp_ps(e_arg_1); - // [−(V0/σ) * e^(−b/σ) * w/(4b), ...] --> scalar + // # 96 MULTs __m512 numer_inv_two_b_0 = _mm512_mul_ps(_mm512_mul_ps(r_sum_0, v_neg_v0_div_2s), _mm512_mul_ps(e_val_0, inv_two_b_0)); __m512 numer_inv_two_b_1 = _mm512_mul_ps(_mm512_mul_ps(r_sum_1, v_neg_v0_div_2s), _mm512_mul_ps(e_val_1, inv_two_b_1)); - // scalar * 1 / |r_ab| + // # 32 MULTs __m512 sm_r_ab_0 = _mm512_mul_ps(numer_inv_two_b_0, inv_r_ab_n_0); __m512 sm_r_ab_1 = _mm512_mul_ps(numer_inv_two_b_1, inv_r_ab_n_1); - // scalar * 1 / |r_ab_2| + // # 32 MULTs __m512 sm_r_ab2_0 = _mm512_mul_ps(numer_inv_two_b_0, inv_r_ab2_n_0); __m512 sm_r_ab2_1 = _mm512_mul_ps(numer_inv_two_b_1, inv_r_ab2_n_1); - // summed force + // # 128 MULTs, 64 ADDs __m512 f_x_0 = _mm512_fmadd_ps(r_ab2_x_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_x_0, sm_r_ab_0)); __m512 f_x_1 = _mm512_fmadd_ps(r_ab2_x_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_x_1, sm_r_ab_1)); __m512 f_y_0 = _mm512_fmadd_ps(r_ab2_y_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_y_0, sm_r_ab_0)); __m512 f_y_1 = _mm512_fmadd_ps(r_ab2_y_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_y_1, sm_r_ab_1)); - // using masking to perform --> field of view formula - // if (e_dot_f >= 0.0 || e_dot_f_sq <= rhs) - // return dt_neg; - // else - // return c_neg_times_dt; - // + // # 64 MULTs, 32 ADDs __m512 f_norm_sq_0 = _mm512_fmadd_ps(f_x_0, f_x_0, _mm512_mul_ps(f_y_0, f_y_0)); __m512 f_norm_sq_1 = _mm512_fmadd_ps(f_x_1, f_x_1, _mm512_mul_ps(f_y_1, f_y_1)); + // # 32 MULTs __m512 rhs_0 = _mm512_mul_ps(f_norm_sq_0, v_cos_phi_sq); __m512 rhs_1 = _mm512_mul_ps(f_norm_sq_1, v_cos_phi_sq); + // # 64 MULTs, 32 ADDs __m512 e_dot_f_0 = _mm512_fmadd_ps(eix, f_x_0, _mm512_mul_ps(eiy, f_y_0)); __m512 e_dot_f_1 = _mm512_fmadd_ps(eix, f_x_1, _mm512_mul_ps(eiy, f_y_1)); + // # 32 MULTs __m512 e_dot_f_sq_0 = _mm512_mul_ps(e_dot_f_0, e_dot_f_0); __m512 e_dot_f_sq_1 = _mm512_mul_ps(e_dot_f_1, e_dot_f_1); - // e_i * f < 0 --> behind __mmask16 c1_0 = _mm512_cmp_ps_mask(e_dot_f_0, v_zero, _CMP_LT_OQ); __mmask16 c1_1 = _mm512_cmp_ps_mask(e_dot_f_1, v_zero, _CMP_LT_OQ); - // (e_i * f)^2 > cos(phi) --> out of view __mmask16 c2_0 = _mm512_cmp_ps_mask(e_dot_f_sq_0, rhs_0, _CMP_GT_OQ); __mmask16 c2_1 = _mm512_cmp_ps_mask(e_dot_f_sq_1, rhs_1, _CMP_GT_OQ); - // get the case (in field of view or not) - // 1 = reduced weight, 0 = regular __mmask16 cond_0 = c1_0 & c2_0; __mmask16 cond_1 = c1_1 & c2_1; - // apply the correct weight __m512 w_val_0 = _mm512_mask_blend_ps(cond_0, v_dt_neg, v_c_neg_dt); __m512 w_val_1 = _mm512_mask_blend_ps(cond_1, v_dt_neg, v_c_neg_dt); - // take care of i == j case by zeroing it out - // see active_0 and active_1 at the beginning of this loop - // [f.x or 0, ...] __m512 f_x_safe_0 = _mm512_maskz_mov_ps(active_0, f_x_0); __m512 f_x_safe_1 = _mm512_maskz_mov_ps(active_1, f_x_1); __m512 f_y_safe_0 = _mm512_maskz_mov_ps(active_0, f_y_0); __m512 f_y_safe_1 = _mm512_maskz_mov_ps(active_1, f_y_1); - // accumulate force with weight - // force_P_total += weight * force_P_other + // # 64 MULTs, 64 ADDs acc_x_0 = _mm512_fmadd_ps(f_x_safe_0, w_val_0, acc_x_0); acc_x_1 = _mm512_fmadd_ps(f_x_safe_1, w_val_1, acc_x_1); acc_y_0 = _mm512_fmadd_ps(f_y_safe_0, w_val_0, acc_y_0); acc_y_1 = _mm512_fmadd_ps(f_y_safe_1, w_val_1, acc_y_1); } - // scalar force accumulator + // # 64 ADDs f_alpha_dt_x += _mm512_reduce_add_ps(_mm512_add_ps(acc_x_0, acc_x_1)); f_alpha_dt_y += _mm512_reduce_add_ps(_mm512_add_ps(acc_y_0, acc_y_1)); - // force between pedestrian and obstacles - // no optimizations, because force between pedestrian is the bottleneck of the computation for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs float v1_x = pos_x[i] - board.obstacles[k].start_x; float v1_y = pos_y[i] - board.obstacles[k].start_y; float v2_x = board.obstacles[k].obstacle_v_x; float v2_y = board.obstacles[k].obstacle_v_y; + // # 3 MULTs, 1 ADD float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; if (projection < 0.0f) @@ -503,12 +480,15 @@ int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, c else if (projection > 1.0f) projection = 1.0f; + // # 4 ADDs, 2 MULTs float r_aB_x = pos_x[i] - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); float r_aB_y = pos_y[i] - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + // # 1 SQRT, 2 MULTs, 1 ADD float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; + // # 4 MULTs, 1 EXP, 1 DIV float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; float f_alpha_B_neg_x = r_aB_x * scalar_mult; float f_alpha_B_neg_y = r_aB_y * scalar_mult; @@ -519,21 +499,21 @@ int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, c if (e_dot_f < cos_phi) w_val = c_neg_times_dt; + // # 2 MULTS float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + // # 2 ADDs f_alpha_dt_x += f_alpha_B_dt_x; f_alpha_dt_y += f_alpha_B_dt_y; } + // # 2 ADDs w_x[i] += f_alpha_dt_x; w_y[i] += f_alpha_dt_y; } - // update each pedestrian for (int i = 0; i < n_p_pad; i += 16) { - // load 16 pedestrians per iteration with their data - // SoA in vectors __m512 w_x_i_vec = _mm512_loadu_ps(&w_x[i]); __m512 w_y_i_vec = _mm512_loadu_ps(&w_y[i]); __m512 v_max_i_vec = _mm512_loadu_ps(&v_max[i]); @@ -545,20 +525,27 @@ int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, c __m512i color_i_vec = _mm512_loadu_si512((__m512i *)&color[i]); + // # 32 MULTs, 16 ADDs __m512 w_norm_sq = _mm512_fmadd_ps(w_x_i_vec, w_x_i_vec, _mm512_mul_ps(w_y_i_vec, w_y_i_vec)); + + // # 16 SQRTs, 16 DIVs __m512 w_norm_inv = _mm512_rsqrt14_ps(w_norm_sq); + + // # 16 MULTs __m512 correction_factor = _mm512_min_ps(_mm512_set1_ps(1.0f), _mm512_mul_ps(v_max_i_vec, w_norm_inv)); + // # 32 MULTs __m512 curr_vel_x_i_vec = _mm512_mul_ps(w_x_i_vec, correction_factor); __m512 curr_vel_y_i_vec = _mm512_mul_ps(w_y_i_vec, correction_factor); __m512 dt_vec = _mm512_set1_ps(dt); + + // # 32 MULTs, 32 ADDs pos_x_i_vec = _mm512_fmadd_ps(curr_vel_x_i_vec, dt_vec, pos_x_i_vec); pos_y_i_vec = _mm512_fmadd_ps(curr_vel_y_i_vec, dt_vec, pos_y_i_vec); - // differentiate whether pedestrian came from left or right using masking __mmask16 cond_1_left = _mm512_cmpeq_epi32_mask(color_i_vec, _mm512_setzero_si512()); - __mmask16 cond_1_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH - 1.5f), _CMP_GT_OQ); + __mmask16 cond_1_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE_POINT_FIVE), _CMP_GT_OQ); __mmask16 cond_1 = cond_1_left & cond_1_right; pos_x_i_vec = _mm512_mask_blend_ps(cond_1, pos_x_i_vec, _mm512_set1_ps(1.0f)); @@ -572,7 +559,7 @@ int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, c __mmask16 cond_2_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(1.5f), _CMP_LT_OQ); __mmask16 cond_2 = cond_2_left & cond_2_right; - pos_x_i_vec = _mm512_mask_blend_ps(cond_2, pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH - 1.0f)); + pos_x_i_vec = _mm512_mask_blend_ps(cond_2, pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE)); destination_y_i_vec = _mm512_mask_blend_ps(cond_2, destination_y_i_vec, pos_y_i_vec); __m512 neg_desired_v0 = _mm512_xor_ps(desired_v0_i_vec, _mm512_set1_ps(-0.0f)); w_x_i_vec = _mm512_mask_blend_ps(cond_2, w_x_i_vec, neg_desired_v0); @@ -583,18 +570,29 @@ int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, c pos_y_i_vec = _mm512_max_ps(pos_y_i_vec, _mm512_set1_ps(WALL_EPS)); pos_y_i_vec = _mm512_min_ps(pos_y_i_vec, _mm512_set1_ps(BOARD_WIDTH_MINUS_WALL_EPS)); + // # 32 ADDs __m512 ex_vec = _mm512_sub_ps(destination_x_i_vec, pos_x_i_vec); __m512 ey_vec = _mm512_sub_ps(destination_y_i_vec, pos_y_i_vec); + + // # 32 MULTs, 16 ADDs __m512 e_norm_sq = _mm512_fmadd_ps(ex_vec, ex_vec, _mm512_mul_ps(ey_vec, ey_vec)); + + // # 16 SQRTs, 16 DIVs __m512 e_norm_inv = _mm512_rsqrt14_ps(e_norm_sq); + + // # 32 MULTs __m512 e_x_i_vec = _mm512_mul_ps(ex_vec, e_norm_inv); __m512 e_y_i_vec = _mm512_mul_ps(ey_vec, e_norm_inv); + // # 32 MULTs, 16 ADDs __m512 vel_norm_sq = _mm512_fmadd_ps(curr_vel_x_i_vec, curr_vel_x_i_vec, _mm512_mul_ps(curr_vel_y_i_vec, curr_vel_y_i_vec)); + + // # 16 MULTs __m512 sb_sq_i_vec = _mm512_mul_ps(vel_norm_sq, _mm512_set1_ps(delta_t_sq)); + + // # 16 SQRTs __m512 vel_norm_dt = _mm512_sqrt_ps(sb_sq_i_vec); - // write the data _mm512_storeu_ps(&curr_vel_x[i], curr_vel_x_i_vec); _mm512_storeu_ps(&curr_vel_y[i], curr_vel_y_i_vec); _mm512_storeu_ps(&w_x[i], w_x_i_vec); @@ -605,6 +603,8 @@ int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, c _mm512_storeu_ps(&e_y[i], e_y_i_vec); _mm512_storeu_ps(&destination_y[i], destination_y_i_vec); _mm512_storeu_ps(&sb_sq[i], sb_sq_i_vec); + + // # 32 MULTs _mm512_storeu_ps(&sb_e_x[i], _mm512_mul_ps(e_x_i_vec, vel_norm_dt)); _mm512_storeu_ps(&sb_e_y[i], _mm512_mul_ps(e_y_i_vec, vel_norm_dt)); } diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved.cpp index 5be10ec..fa51a70 100644 --- a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved.cpp +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved.cpp @@ -176,6 +176,7 @@ static inline __m512 _avx512_exp_ps(__m512 x) { // # 16 MULTs, 16 ADDs __m512 r = _mm512_fnmadd_ps(nf, ln2, x); + const __m512 c13 = _mm512_set1_ps(c13_scalar); const __m512 c12 = _mm512_set1_ps(c12_scalar); const __m512 c11 = _mm512_set1_ps(c11_scalar); const __m512 c10 = _mm512_set1_ps(c10_scalar); @@ -190,7 +191,7 @@ static inline __m512 _avx512_exp_ps(__m512 x) { const __m512 c1 = _mm512_set1_ps(c1_scalar); const __m512 c0 = _mm512_set1_ps(c0_scalar); - __m512 p = c12; + __m512 p = c13; // # 13 * (16 MULTs, 16 ADDs) // # = 208 MULTs, 208 ADDs diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp.cpp index eb21dc4..c1cf0b7 100644 --- a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp.cpp +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2_rsqrt_morersqrt_expfix_improved_moreilp.cpp @@ -174,6 +174,7 @@ static inline __m512 _avx512_exp_ps(__m512 x) { // # 16 MULTs, 16 ADDs __m512 r = _mm512_fnmadd_ps(nf, ln2, x); + const __m512 c13 = _mm512_set1_ps(c13_scalar); const __m512 c12 = _mm512_set1_ps(c12_scalar); const __m512 c11 = _mm512_set1_ps(c11_scalar); const __m512 c10 = _mm512_set1_ps(c10_scalar); @@ -188,7 +189,7 @@ static inline __m512 _avx512_exp_ps(__m512 x) { const __m512 c1 = _mm512_set1_ps(c1_scalar); const __m512 c0 = _mm512_set1_ps(c0_scalar); - __m512 p = c12; + __m512 p = c13; // # 13 * (16 MULTs, 16 ADDs) // # = 208 MULTs, 208 ADDs diff --git a/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix.cpp b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix.cpp new file mode 100644 index 0000000..1548d65 --- /dev/null +++ b/variants/variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_4_expfix.cpp @@ -0,0 +1,727 @@ +// # Changes: Added ILP with k = 4 to j-loop +// # Predecessor: variant_float_inlining_SoA_AVX512_polyexp_moreavx_ilp_2.cpp + +#include "../headers/board_reduced_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_reduced_float.hpp" + +#include + +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0f +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 63) & ~63; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + float dest_x = BOARD_LENGTH + 30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + float dest_x = -30.0f; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1f); + + float v_m = 1.3f * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9f; + pos_y[j] = 1e9f; + sb_sq[j] = 0.0f; + sb_e_x[j] = 0.0f; + sb_e_y[j] = 0.0f; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 256 MULTs, 224 ADDs +static inline __m512 _avx512_exp_ps(__m512 x) { + + const __m512 log2e = _mm512_set1_ps(1.4426950408889634f); + + // # 16 MULTs + __m512 nf = _mm512_roundscale_ps(_mm512_mul_ps(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + + const __m512 ln2 = _mm512_set1_ps(0.6931471805599453f); + + // # 16 MULTs, 16 ADDs + __m512 r = _mm512_fnmadd_ps(nf, ln2, x); + + const __m512 c13 = _mm512_set1_ps(c13_scalar); + const __m512 c12 = _mm512_set1_ps(c12_scalar); + const __m512 c11 = _mm512_set1_ps(c11_scalar); + const __m512 c10 = _mm512_set1_ps(c10_scalar); + const __m512 c9 = _mm512_set1_ps(c9_scalar); + const __m512 c8 = _mm512_set1_ps(c8_scalar); + const __m512 c7 = _mm512_set1_ps(c7_scalar); + const __m512 c6 = _mm512_set1_ps(c6_scalar); + const __m512 c5 = _mm512_set1_ps(c5_scalar); + const __m512 c4 = _mm512_set1_ps(c4_scalar); + const __m512 c3 = _mm512_set1_ps(c3_scalar); + const __m512 c2 = _mm512_set1_ps(c2_scalar); + const __m512 c1 = _mm512_set1_ps(c1_scalar); + const __m512 c0 = _mm512_set1_ps(c0_scalar); + + __m512 p = c13; + + // # 13 * (16 MULTs, 16 ADDs) + // # = 208 MULTs, 208 ADDs + p = _mm512_fmadd_ps(p, r, c12); + p = _mm512_fmadd_ps(p, r, c11); + p = _mm512_fmadd_ps(p, r, c10); + p = _mm512_fmadd_ps(p, r, c9); + p = _mm512_fmadd_ps(p, r, c8); + p = _mm512_fmadd_ps(p, r, c7); + p = _mm512_fmadd_ps(p, r, c6); + p = _mm512_fmadd_ps(p, r, c5); + p = _mm512_fmadd_ps(p, r, c4); + p = _mm512_fmadd_ps(p, r, c3); + p = _mm512_fmadd_ps(p, r, c2); + p = _mm512_fmadd_ps(p, r, c1); + p = _mm512_fmadd_ps(p, r, c0); + + __m512i ni = _mm512_cvtps_epi32(nf); + __m512i biased = _mm512_add_epi32(ni, _mm512_set1_epi32(127)); + __m512i scaled = _mm512_slli_epi32(biased, 23); + __m512 pow2n = _mm512_castsi512_ps(scaled); + + // # 16 MULTs + return _mm512_mul_ps(p, pow2n); +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + (void)pedestrians; +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 63) & ~63; + + alignas(64) const float lane_offset_arr[16] = {0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f}; + const __m512 lane_off = _mm512_load_ps(lane_offset_arr); + + const __m512 v_neg_v0_div_2s = _mm512_set1_ps(NEG_V0_AB_div_TWO_SIGMA); + const __m512 v_neg_2s_inv = _mm512_set1_ps(NEG_TWO_SIGMA_INV); + const __m512 v_cos_phi_sq = _mm512_set1_ps(cos_phi_sq); + const __m512 v_dt_neg = _mm512_set1_ps(dt_neg); + const __m512 v_c_neg_dt = _mm512_set1_ps(c_neg_times_dt); + const __m512 v_zero = _mm512_setzero_ps(); + const __m512 v_one = _mm512_set1_ps(1.0f); + const __m512 v_eps = _mm512_set1_ps(EPS); + const __m512 v_eps_sq = _mm512_set1_ps(EPS_SQ); + const __m512 v_np = _mm512_set1_ps((float)n_p); + const __m512 v_exp_min = _mm512_set1_ps(-87.0f); + + // # ADDs: n_iter * ( + // # n_p * 132 + + // # n_p * n_p_pad * 29 + + // # n_p * board.n_obstacles * 10 + + // # n_p_pad * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + + // # n_p * n_p_pad * 40 + + // # n_p * board.n_obstacles * 13 + + // # n_p_pad * 15 + // # ) + + // # DIVs: n_iter * ( + // # n_p * n_p_pad + + // # n_p * board.n_obstacles + + // # n_p_pad * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * n_p_pad * 3 + + // # n_p * board.n_obstacles + + // # n_p_pad * 3 + // # ) + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + + // # 2 MULTs + float desired_velocity_x = e_x[i] * desired_v0[i]; + float desired_velocity_y = e_y[i] * desired_v0[i]; + + // # 2 ADDs, 2 MULTs + float f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; + float f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; + + const __m512 pix = _mm512_set1_ps(pos_x[i]); + const __m512 piy = _mm512_set1_ps(pos_y[i]); + const __m512 eix = _mm512_set1_ps(e_x[i]); + const __m512 eiy = _mm512_set1_ps(e_y[i]); + const __m512 v_i = _mm512_set1_ps((float)i); + + __m512 acc_x_0 = _mm512_setzero_ps(); + __m512 acc_x_1 = _mm512_setzero_ps(); + __m512 acc_x_2 = _mm512_setzero_ps(); + __m512 acc_x_3 = _mm512_setzero_ps(); + + __m512 acc_y_0 = _mm512_setzero_ps(); + __m512 acc_y_1 = _mm512_setzero_ps(); + __m512 acc_y_2 = _mm512_setzero_ps(); + __m512 acc_y_3 = _mm512_setzero_ps(); + + for (int j = 0; j < n_p_pad; j += 64) { + + // # 64 ADDs + __m512 j_idx_0 = _mm512_add_ps(_mm512_set1_ps((float)j), lane_off); + __m512 j_idx_1 = _mm512_add_ps(_mm512_set1_ps((float)j + 16), lane_off); + __m512 j_idx_2 = _mm512_add_ps(_mm512_set1_ps((float)j + 32), lane_off); + __m512 j_idx_3 = _mm512_add_ps(_mm512_set1_ps((float)j + 48), lane_off); + + __mmask16 m_neq_i_0 = _mm512_cmp_ps_mask(j_idx_0, v_i, _CMP_NEQ_OQ); + __mmask16 m_neq_i_1 = _mm512_cmp_ps_mask(j_idx_1, v_i, _CMP_NEQ_OQ); + __mmask16 m_neq_i_2 = _mm512_cmp_ps_mask(j_idx_2, v_i, _CMP_NEQ_OQ); + __mmask16 m_neq_i_3 = _mm512_cmp_ps_mask(j_idx_3, v_i, _CMP_NEQ_OQ); + + __mmask16 m_in_range_0 = _mm512_cmp_ps_mask(j_idx_0, v_np, _CMP_LT_OQ); + __mmask16 m_in_range_1 = _mm512_cmp_ps_mask(j_idx_1, v_np, _CMP_LT_OQ); + __mmask16 m_in_range_2 = _mm512_cmp_ps_mask(j_idx_2, v_np, _CMP_LT_OQ); + __mmask16 m_in_range_3 = _mm512_cmp_ps_mask(j_idx_3, v_np, _CMP_LT_OQ); + + __mmask16 active_0 = m_neq_i_0 & m_in_range_0; + __mmask16 active_1 = m_neq_i_1 & m_in_range_1; + __mmask16 active_2 = m_neq_i_2 & m_in_range_2; + __mmask16 active_3 = m_neq_i_3 & m_in_range_3; + + __m512 pjx_0 = _mm512_loadu_ps(&pos_x[j]); + __m512 pjx_1 = _mm512_loadu_ps(&pos_x[j + 16]); + __m512 pjx_2 = _mm512_loadu_ps(&pos_x[j + 32]); + __m512 pjx_3 = _mm512_loadu_ps(&pos_x[j + 48]); + + __m512 pjy_0 = _mm512_loadu_ps(&pos_y[j]); + __m512 pjy_1 = _mm512_loadu_ps(&pos_y[j + 16]); + __m512 pjy_2 = _mm512_loadu_ps(&pos_y[j + 32]); + __m512 pjy_3 = _mm512_loadu_ps(&pos_y[j + 48]); + + __m512 sbe_jx_0 = _mm512_loadu_ps(&sb_e_x[j]); + __m512 sbe_jx_1 = _mm512_loadu_ps(&sb_e_x[j + 16]); + __m512 sbe_jx_2 = _mm512_loadu_ps(&sb_e_x[j + 32]); + __m512 sbe_jx_3 = _mm512_loadu_ps(&sb_e_x[j + 48]); + + __m512 sbe_jy_0 = _mm512_loadu_ps(&sb_e_y[j]); + __m512 sbe_jy_1 = _mm512_loadu_ps(&sb_e_y[j + 16]); + __m512 sbe_jy_2 = _mm512_loadu_ps(&sb_e_y[j + 32]); + __m512 sbe_jy_3 = _mm512_loadu_ps(&sb_e_y[j + 48]); + + __m512 sb_jsq_0 = _mm512_loadu_ps(&sb_sq[j]); + __m512 sb_jsq_1 = _mm512_loadu_ps(&sb_sq[j + 16]); + __m512 sb_jsq_2 = _mm512_loadu_ps(&sb_sq[j + 32]); + __m512 sb_jsq_3 = _mm512_loadu_ps(&sb_sq[j + 48]); + + // # 64 ADDs + __m512 r_ab_x_0 = _mm512_sub_ps(pix, pjx_0); + __m512 r_ab_x_1 = _mm512_sub_ps(pix, pjx_1); + __m512 r_ab_x_2 = _mm512_sub_ps(pix, pjx_2); + __m512 r_ab_x_3 = _mm512_sub_ps(pix, pjx_3); + + // # 64 ADDs + __m512 r_ab_y_0 = _mm512_sub_ps(piy, pjy_0); + __m512 r_ab_y_1 = _mm512_sub_ps(piy, pjy_1); + __m512 r_ab_y_2 = _mm512_sub_ps(piy, pjy_2); + __m512 r_ab_y_3 = _mm512_sub_ps(piy, pjy_3); + + // # 128 MULTs, 64 ADDs + __m512 r_ab_n2_0 = _mm512_fmadd_ps(r_ab_x_0, r_ab_x_0, _mm512_mul_ps(r_ab_y_0, r_ab_y_0)); + __m512 r_ab_n2_1 = _mm512_fmadd_ps(r_ab_x_1, r_ab_x_1, _mm512_mul_ps(r_ab_y_1, r_ab_y_1)); + __m512 r_ab_n2_2 = _mm512_fmadd_ps(r_ab_x_2, r_ab_x_2, _mm512_mul_ps(r_ab_y_2, r_ab_y_2)); + __m512 r_ab_n2_3 = _mm512_fmadd_ps(r_ab_x_3, r_ab_x_3, _mm512_mul_ps(r_ab_y_3, r_ab_y_3)); + + // # 64 SQRTs + __m512 r_ab_n_0 = _mm512_sqrt_ps(r_ab_n2_0); + __m512 r_ab_n_1 = _mm512_sqrt_ps(r_ab_n2_1); + __m512 r_ab_n_2 = _mm512_sqrt_ps(r_ab_n2_2); + __m512 r_ab_n_3 = _mm512_sqrt_ps(r_ab_n2_3); + + // # 64 ADDs + __m512 r_ab2_x_0 = _mm512_sub_ps(r_ab_x_0, sbe_jx_0); + __m512 r_ab2_x_1 = _mm512_sub_ps(r_ab_x_1, sbe_jx_1); + __m512 r_ab2_x_2 = _mm512_sub_ps(r_ab_x_2, sbe_jx_2); + __m512 r_ab2_x_3 = _mm512_sub_ps(r_ab_x_3, sbe_jx_3); + + // # 64 ADDs + __m512 r_ab2_y_0 = _mm512_sub_ps(r_ab_y_0, sbe_jy_0); + __m512 r_ab2_y_1 = _mm512_sub_ps(r_ab_y_1, sbe_jy_1); + __m512 r_ab2_y_2 = _mm512_sub_ps(r_ab_y_2, sbe_jy_2); + __m512 r_ab2_y_3 = _mm512_sub_ps(r_ab_y_3, sbe_jy_3); + + // # 128 MULTs, 64 ADDs + __m512 r_ab2_n2_0 = _mm512_fmadd_ps(r_ab2_x_0, r_ab2_x_0, _mm512_mul_ps(r_ab2_y_0, r_ab2_y_0)); + __m512 r_ab2_n2_1 = _mm512_fmadd_ps(r_ab2_x_1, r_ab2_x_1, _mm512_mul_ps(r_ab2_y_1, r_ab2_y_1)); + __m512 r_ab2_n2_2 = _mm512_fmadd_ps(r_ab2_x_2, r_ab2_x_2, _mm512_mul_ps(r_ab2_y_2, r_ab2_y_2)); + __m512 r_ab2_n2_3 = _mm512_fmadd_ps(r_ab2_x_3, r_ab2_x_3, _mm512_mul_ps(r_ab2_y_3, r_ab2_y_3)); + + // # 64 SQRTs + __m512 r_ab2_n_0 = _mm512_sqrt_ps(r_ab2_n2_0); + __m512 r_ab2_n_1 = _mm512_sqrt_ps(r_ab2_n2_1); + __m512 r_ab2_n_2 = _mm512_sqrt_ps(r_ab2_n2_2); + __m512 r_ab2_n_3 = _mm512_sqrt_ps(r_ab2_n2_3); + + // # 64 ADDs + __m512 r_sum_0 = _mm512_add_ps(r_ab_n_0, r_ab2_n_0); + __m512 r_sum_1 = _mm512_add_ps(r_ab_n_1, r_ab2_n_1); + __m512 r_sum_2 = _mm512_add_ps(r_ab_n_2, r_ab2_n_2); + __m512 r_sum_3 = _mm512_add_ps(r_ab_n_3, r_ab2_n_3); + + // # 64 MULTs, 64 ADDs + __m512 two_b_sq_0 = _mm512_fmsub_ps(r_sum_0, r_sum_0, sb_jsq_0); + __m512 two_b_sq_1 = _mm512_fmsub_ps(r_sum_1, r_sum_1, sb_jsq_1); + __m512 two_b_sq_2 = _mm512_fmsub_ps(r_sum_2, r_sum_2, sb_jsq_2); + __m512 two_b_sq_3 = _mm512_fmsub_ps(r_sum_3, r_sum_3, sb_jsq_3); + + // # 64 SQRTs + __m512 two_b_0 = _mm512_sqrt_ps(two_b_sq_0); + __m512 two_b_1 = _mm512_sqrt_ps(two_b_sq_1); + __m512 two_b_2 = _mm512_sqrt_ps(two_b_sq_2); + __m512 two_b_3 = _mm512_sqrt_ps(two_b_sq_3); + + // # 64 MULTs + __m512 e_arg_0 = _mm512_mul_ps(two_b_0, v_neg_2s_inv); + __m512 e_arg_1 = _mm512_mul_ps(two_b_1, v_neg_2s_inv); + __m512 e_arg_2 = _mm512_mul_ps(two_b_2, v_neg_2s_inv); + __m512 e_arg_3 = _mm512_mul_ps(two_b_3, v_neg_2s_inv); + + e_arg_0 = _mm512_max_ps(e_arg_0, v_exp_min); + e_arg_1 = _mm512_max_ps(e_arg_1, v_exp_min); + e_arg_2 = _mm512_max_ps(e_arg_2, v_exp_min); + e_arg_3 = _mm512_max_ps(e_arg_3, v_exp_min); + + // # 1024 MULTs, 896 ADDs + __m512 e_val_0 = _avx512_exp_ps(e_arg_0); + __m512 e_val_1 = _avx512_exp_ps(e_arg_1); + __m512 e_val_2 = _avx512_exp_ps(e_arg_2); + __m512 e_val_3 = _avx512_exp_ps(e_arg_3); + + // # 128 MULTs + __m512 numer_0 = _mm512_mul_ps(_mm512_mul_ps(r_sum_0, v_neg_v0_div_2s), e_val_0); + __m512 numer_1 = _mm512_mul_ps(_mm512_mul_ps(r_sum_1, v_neg_v0_div_2s), e_val_1); + __m512 numer_2 = _mm512_mul_ps(_mm512_mul_ps(r_sum_2, v_neg_v0_div_2s), e_val_2); + __m512 numer_3 = _mm512_mul_ps(_mm512_mul_ps(r_sum_3, v_neg_v0_div_2s), e_val_3); + + // # 128 MULTs + __m512 denom_0 = _mm512_mul_ps(_mm512_mul_ps(two_b_0, r_ab_n_0), r_ab2_n_0); + __m512 denom_1 = _mm512_mul_ps(_mm512_mul_ps(two_b_1, r_ab_n_1), r_ab2_n_1); + __m512 denom_2 = _mm512_mul_ps(_mm512_mul_ps(two_b_2, r_ab_n_2), r_ab2_n_2); + __m512 denom_3 = _mm512_mul_ps(_mm512_mul_ps(two_b_3, r_ab_n_3), r_ab2_n_3); + + __m512 denom_safe_0 = _mm512_mask_blend_ps(active_0, v_one, denom_0); + __m512 denom_safe_1 = _mm512_mask_blend_ps(active_1, v_one, denom_1); + __m512 denom_safe_2 = _mm512_mask_blend_ps(active_2, v_one, denom_2); + __m512 denom_safe_3 = _mm512_mask_blend_ps(active_3, v_one, denom_3); + + // # 64 DIVs + __m512 smc_0 = _mm512_div_ps(numer_0, denom_safe_0); + __m512 smc_1 = _mm512_div_ps(numer_1, denom_safe_1); + __m512 smc_2 = _mm512_div_ps(numer_2, denom_safe_2); + __m512 smc_3 = _mm512_div_ps(numer_3, denom_safe_3); + + // # 64 MULTs + __m512 sm_r_ab_0 = _mm512_mul_ps(smc_0, r_ab2_n_0); + __m512 sm_r_ab_1 = _mm512_mul_ps(smc_1, r_ab2_n_1); + __m512 sm_r_ab_2 = _mm512_mul_ps(smc_2, r_ab2_n_2); + __m512 sm_r_ab_3 = _mm512_mul_ps(smc_3, r_ab2_n_3); + + // # 64 MULTs + __m512 sm_r_ab2_0 = _mm512_mul_ps(smc_0, r_ab_n_0); + __m512 sm_r_ab2_1 = _mm512_mul_ps(smc_1, r_ab_n_1); + __m512 sm_r_ab2_2 = _mm512_mul_ps(smc_2, r_ab_n_2); + __m512 sm_r_ab2_3 = _mm512_mul_ps(smc_3, r_ab_n_3); + + // # 128 MULTs, 64 ADDs + __m512 f_x_0 = _mm512_fmadd_ps(r_ab2_x_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_x_0, sm_r_ab_0)); + __m512 f_x_1 = _mm512_fmadd_ps(r_ab2_x_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_x_1, sm_r_ab_1)); + __m512 f_x_2 = _mm512_fmadd_ps(r_ab2_x_2, sm_r_ab2_2, _mm512_mul_ps(r_ab_x_2, sm_r_ab_2)); + __m512 f_x_3 = _mm512_fmadd_ps(r_ab2_x_3, sm_r_ab2_3, _mm512_mul_ps(r_ab_x_3, sm_r_ab_3)); + + // # 128 MULTs, 64 ADDs + __m512 f_y_0 = _mm512_fmadd_ps(r_ab2_y_0, sm_r_ab2_0, _mm512_mul_ps(r_ab_y_0, sm_r_ab_0)); + __m512 f_y_1 = _mm512_fmadd_ps(r_ab2_y_1, sm_r_ab2_1, _mm512_mul_ps(r_ab_y_1, sm_r_ab_1)); + __m512 f_y_2 = _mm512_fmadd_ps(r_ab2_y_2, sm_r_ab2_2, _mm512_mul_ps(r_ab_y_2, sm_r_ab_2)); + __m512 f_y_3 = _mm512_fmadd_ps(r_ab2_y_3, sm_r_ab2_3, _mm512_mul_ps(r_ab_y_3, sm_r_ab_3)); + + // # 128 MULTs, 64 ADDs + __m512 f_norm_sq_0 = _mm512_fmadd_ps(f_x_0, f_x_0, _mm512_mul_ps(f_y_0, f_y_0)); + __m512 f_norm_sq_1 = _mm512_fmadd_ps(f_x_1, f_x_1, _mm512_mul_ps(f_y_1, f_y_1)); + __m512 f_norm_sq_2 = _mm512_fmadd_ps(f_x_2, f_x_2, _mm512_mul_ps(f_y_2, f_y_2)); + __m512 f_norm_sq_3 = _mm512_fmadd_ps(f_x_3, f_x_3, _mm512_mul_ps(f_y_3, f_y_3)); + + // # 64 MULTs + __m512 rhs_0 = _mm512_mul_ps(f_norm_sq_0, v_cos_phi_sq); + __m512 rhs_1 = _mm512_mul_ps(f_norm_sq_1, v_cos_phi_sq); + __m512 rhs_2 = _mm512_mul_ps(f_norm_sq_2, v_cos_phi_sq); + __m512 rhs_3 = _mm512_mul_ps(f_norm_sq_3, v_cos_phi_sq); + + // # 128 MULTs, 64 ADDs + __m512 e_dot_f_0 = _mm512_fmadd_ps(eix, f_x_0, _mm512_mul_ps(eiy, f_y_0)); + __m512 e_dot_f_1 = _mm512_fmadd_ps(eix, f_x_1, _mm512_mul_ps(eiy, f_y_1)); + __m512 e_dot_f_2 = _mm512_fmadd_ps(eix, f_x_2, _mm512_mul_ps(eiy, f_y_2)); + __m512 e_dot_f_3 = _mm512_fmadd_ps(eix, f_x_3, _mm512_mul_ps(eiy, f_y_3)); + + // # 64 MULTs + __m512 e_dot_f_sq_0 = _mm512_mul_ps(e_dot_f_0, e_dot_f_0); + __m512 e_dot_f_sq_1 = _mm512_mul_ps(e_dot_f_1, e_dot_f_1); + __m512 e_dot_f_sq_2 = _mm512_mul_ps(e_dot_f_2, e_dot_f_2); + __m512 e_dot_f_sq_3 = _mm512_mul_ps(e_dot_f_3, e_dot_f_3); + + __mmask16 c1_0 = _mm512_cmp_ps_mask(e_dot_f_0, v_zero, _CMP_LT_OQ); + __mmask16 c1_1 = _mm512_cmp_ps_mask(e_dot_f_1, v_zero, _CMP_LT_OQ); + __mmask16 c1_2 = _mm512_cmp_ps_mask(e_dot_f_2, v_zero, _CMP_LT_OQ); + __mmask16 c1_3 = _mm512_cmp_ps_mask(e_dot_f_3, v_zero, _CMP_LT_OQ); + + __mmask16 c2_0 = _mm512_cmp_ps_mask(e_dot_f_sq_0, rhs_0, _CMP_GT_OQ); + __mmask16 c2_1 = _mm512_cmp_ps_mask(e_dot_f_sq_1, rhs_1, _CMP_GT_OQ); + __mmask16 c2_2 = _mm512_cmp_ps_mask(e_dot_f_sq_2, rhs_2, _CMP_GT_OQ); + __mmask16 c2_3 = _mm512_cmp_ps_mask(e_dot_f_sq_3, rhs_3, _CMP_GT_OQ); + + __mmask16 cond_0 = c1_0 & c2_0; + __mmask16 cond_1 = c1_1 & c2_1; + __mmask16 cond_2 = c1_2 & c2_2; + __mmask16 cond_3 = c1_3 & c2_3; + + __m512 w_val_0 = _mm512_mask_blend_ps(cond_0, v_dt_neg, v_c_neg_dt); + __m512 w_val_1 = _mm512_mask_blend_ps(cond_1, v_dt_neg, v_c_neg_dt); + __m512 w_val_2 = _mm512_mask_blend_ps(cond_2, v_dt_neg, v_c_neg_dt); + __m512 w_val_3 = _mm512_mask_blend_ps(cond_3, v_dt_neg, v_c_neg_dt); + + __m512 f_x_safe_0 = _mm512_maskz_mov_ps(active_0, f_x_0); + __m512 f_x_safe_1 = _mm512_maskz_mov_ps(active_1, f_x_1); + __m512 f_x_safe_2 = _mm512_maskz_mov_ps(active_2, f_x_2); + __m512 f_x_safe_3 = _mm512_maskz_mov_ps(active_3, f_x_3); + + __m512 f_y_safe_0 = _mm512_maskz_mov_ps(active_0, f_y_0); + __m512 f_y_safe_1 = _mm512_maskz_mov_ps(active_1, f_y_1); + __m512 f_y_safe_2 = _mm512_maskz_mov_ps(active_2, f_y_2); + __m512 f_y_safe_3 = _mm512_maskz_mov_ps(active_3, f_y_3); + + // # 64 MULTs, 64 ADDs + acc_x_0 = _mm512_fmadd_ps(f_x_safe_0, w_val_0, acc_x_0); + acc_x_1 = _mm512_fmadd_ps(f_x_safe_1, w_val_1, acc_x_1); + acc_x_2 = _mm512_fmadd_ps(f_x_safe_2, w_val_2, acc_x_2); + acc_x_3 = _mm512_fmadd_ps(f_x_safe_3, w_val_3, acc_x_3); + + // # 64 MULTs, 64 ADDs + acc_y_0 = _mm512_fmadd_ps(f_y_safe_0, w_val_0, acc_y_0); + acc_y_1 = _mm512_fmadd_ps(f_y_safe_1, w_val_1, acc_y_1); + acc_y_2 = _mm512_fmadd_ps(f_y_safe_2, w_val_2, acc_y_2); + acc_y_3 = _mm512_fmadd_ps(f_y_safe_3, w_val_3, acc_y_3); + } + // # 128 ADDs + f_alpha_dt_x += _mm512_reduce_add_ps(_mm512_add_ps(_mm512_add_ps(acc_x_0, acc_x_1), _mm512_add_ps(acc_x_2, acc_x_3))); + f_alpha_dt_y += _mm512_reduce_add_ps(_mm512_add_ps(_mm512_add_ps(acc_y_0, acc_y_1), _mm512_add_ps(acc_y_2, acc_y_3))); + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + float v1_x = pos_x[i] - board.obstacles[k].start_x; + float v1_y = pos_y[i] - board.obstacles[k].start_y; + float v2_x = board.obstacles[k].obstacle_v_x; + float v2_y = board.obstacles[k].obstacle_v_y; + + // # 3 MULTs, 1 ADD + float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0f) + projection = 0.0f; + else if (projection > 1.0f) + projection = 1.0f; + + // # 4 ADDs, 2 MULTs + float r_aB_x = pos_x[i] - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + float r_aB_y = pos_y[i] - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; + + // # 1 EXP, 4 MULTs, 1 DIV + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + float f_alpha_B_neg_x = r_aB_x * scalar_mult; + float f_alpha_B_neg_y = r_aB_y * scalar_mult; + + float w_val = dt_neg; + float e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y[i] : e_y[i]); + + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTs + float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p_pad; i += 16) { + + __m512 w_x_i_vec = _mm512_loadu_ps(&w_x[i]); + __m512 w_y_i_vec = _mm512_loadu_ps(&w_y[i]); + __m512 v_max_i_vec = _mm512_loadu_ps(&v_max[i]); + __m512 pos_x_i_vec = _mm512_loadu_ps(&pos_x[i]); + __m512 pos_y_i_vec = _mm512_loadu_ps(&pos_y[i]); + __m512 destination_y_i_vec = _mm512_loadu_ps(&destination_y[i]); + __m512 destination_x_i_vec = _mm512_loadu_ps(&destination_x[i]); + __m512 desired_v0_i_vec = _mm512_loadu_ps(&desired_v0[i]); + + __m512i color_i_vec = _mm512_loadu_si512((__m512i *)&color[i]); + + // # 32 MULTs, 16 ADDs + __m512 w_norm_sq = _mm512_fmadd_ps(w_x_i_vec, w_x_i_vec, _mm512_mul_ps(w_y_i_vec, w_y_i_vec)); + + // # 16 SQRTs + __m512 w_norm = _mm512_sqrt_ps(w_norm_sq); + + // # 16 DIVs + __m512 correction_factor = _mm512_min_ps(_mm512_set1_ps(1.0f), _mm512_div_ps(v_max_i_vec, w_norm)); + + // # 32 MULTs + __m512 curr_vel_x_i_vec = _mm512_mul_ps(w_x_i_vec, correction_factor); + __m512 curr_vel_y_i_vec = _mm512_mul_ps(w_y_i_vec, correction_factor); + + __m512 dt_vec = _mm512_set1_ps(dt); + + // # 32 MULTs, 32 ADDs + pos_x_i_vec = _mm512_fmadd_ps(curr_vel_x_i_vec, dt_vec, pos_x_i_vec); + pos_y_i_vec = _mm512_fmadd_ps(curr_vel_y_i_vec, dt_vec, pos_y_i_vec); + + __mmask16 cond_1_left = _mm512_cmpeq_epi32_mask(color_i_vec, _mm512_setzero_si512()); + __mmask16 cond_1_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE_POINT_FIVE), _CMP_GT_OQ); + __mmask16 cond_1 = cond_1_left & cond_1_right; + + pos_x_i_vec = _mm512_mask_blend_ps(cond_1, pos_x_i_vec, _mm512_set1_ps(1.0f)); + destination_y_i_vec = _mm512_mask_blend_ps(cond_1, destination_y_i_vec, pos_y_i_vec); + w_x_i_vec = _mm512_mask_blend_ps(cond_1, w_x_i_vec, desired_v0_i_vec); + w_y_i_vec = _mm512_mask_blend_ps(cond_1, w_y_i_vec, _mm512_setzero_ps()); + curr_vel_x_i_vec = _mm512_mask_blend_ps(cond_1, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_ps(cond_1, curr_vel_y_i_vec, w_y_i_vec); + + __mmask16 cond_2_left = _mm512_cmpeq_epi32_mask(color_i_vec, _mm512_set1_epi32(1)); + __mmask16 cond_2_right = _mm512_cmp_ps_mask(pos_x_i_vec, _mm512_set1_ps(1.5f), _CMP_LT_OQ); + __mmask16 cond_2 = cond_2_left & cond_2_right; + + pos_x_i_vec = _mm512_mask_blend_ps(cond_2, pos_x_i_vec, _mm512_set1_ps(BOARD_LENGTH_MINUS_ONE)); + destination_y_i_vec = _mm512_mask_blend_ps(cond_2, destination_y_i_vec, pos_y_i_vec); + __m512 neg_desired_v0 = _mm512_xor_ps(desired_v0_i_vec, _mm512_set1_ps(-0.0f)); + w_x_i_vec = _mm512_mask_blend_ps(cond_2, w_x_i_vec, neg_desired_v0); + w_y_i_vec = _mm512_mask_blend_ps(cond_2, w_y_i_vec, _mm512_setzero_ps()); + curr_vel_x_i_vec = _mm512_mask_blend_ps(cond_2, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_ps(cond_2, curr_vel_y_i_vec, w_y_i_vec); + + pos_y_i_vec = _mm512_max_ps(pos_y_i_vec, _mm512_set1_ps(WALL_EPS)); + pos_y_i_vec = _mm512_min_ps(pos_y_i_vec, _mm512_set1_ps(BOARD_WIDTH_MINUS_WALL_EPS)); + + // # 32 ADDs + __m512 ex_vec = _mm512_sub_ps(destination_x_i_vec, pos_x_i_vec); + __m512 ey_vec = _mm512_sub_ps(destination_y_i_vec, pos_y_i_vec); + + // # 32 MULTs, 16 ADDs + __m512 e_norm_sq = _mm512_fmadd_ps(ex_vec, ex_vec, _mm512_mul_ps(ey_vec, ey_vec)); + + // # 16 SQRTs + __m512 e_norm = _mm512_sqrt_ps(e_norm_sq); + + // # 16 DIVs + __m512 e_norm_inv = _mm512_div_ps(_mm512_set1_ps(1.0f), e_norm); + + // # 32 MULTs + __m512 e_x_i_vec = _mm512_mul_ps(ex_vec, e_norm_inv); + __m512 e_y_i_vec = _mm512_mul_ps(ey_vec, e_norm_inv); + + // # 32 MULTs, 16 ADDs + __m512 vel_norm_sq = _mm512_fmadd_ps(curr_vel_x_i_vec, curr_vel_x_i_vec, _mm512_mul_ps(curr_vel_y_i_vec, curr_vel_y_i_vec)); + + // # 16 MULTs + __m512 sb_sq_i_vec = _mm512_mul_ps(vel_norm_sq, _mm512_set1_ps(delta_t_sq)); + + // # 16 SQRTs + __m512 vel_norm_dt = _mm512_sqrt_ps(sb_sq_i_vec); + + _mm512_storeu_ps(&curr_vel_x[i], curr_vel_x_i_vec); + _mm512_storeu_ps(&curr_vel_y[i], curr_vel_y_i_vec); + _mm512_storeu_ps(&w_x[i], w_x_i_vec); + _mm512_storeu_ps(&w_y[i], w_y_i_vec); + _mm512_storeu_ps(&pos_x[i], pos_x_i_vec); + _mm512_storeu_ps(&pos_y[i], pos_y_i_vec); + _mm512_storeu_ps(&e_x[i], e_x_i_vec); + _mm512_storeu_ps(&e_y[i], e_y_i_vec); + _mm512_storeu_ps(&destination_y[i], destination_y_i_vec); + _mm512_storeu_ps(&sb_sq[i], sb_sq_i_vec); + + // # 32 MULTs + _mm512_storeu_ps(&sb_e_x[i], _mm512_mul_ps(e_x_i_vec, vel_norm_dt)); + _mm512_storeu_ps(&sb_e_y[i], _mm512_mul_ps(e_y_i_vec, vel_norm_dt)); + } + +#if !BENCHMARK + for (int i = 0; i < n_p; i++) { + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_float_inlining_SoA_flopcount.cpp b/variants/variant_float_inlining_SoA_flopcount.cpp new file mode 100644 index 0000000..1842150 --- /dev/null +++ b/variants/variant_float_inlining_SoA_flopcount.cpp @@ -0,0 +1,380 @@ +// # Changes: SoA layout for pedestrians (file-scope arrays instead of struct fields) +// # Predecessor: variant_float_inlining.cpp + +#include "../headers/board_reduced_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_reduced_float.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +// we wanna use arrays so we can implement SoA, one array per pedestrian field +vector pos_x, pos_y; +vector sb_sq; +vector sb_e_x, sb_e_y; +vector e_x, e_y; +vector curr_vel_x, curr_vel_y; +vector w_x, w_y; +vector desired_v0; +vector v_max; +vector destination_x, destination_y; +vector color; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + // resize all arrays for this run + pos_x.resize(n_p); + pos_y.resize(n_p); + sb_sq.resize(n_p); + sb_e_x.resize(n_p); + sb_e_y.resize(n_p); + e_x.resize(n_p); + e_y.resize(n_p); + curr_vel_x.resize(n_p); + curr_vel_y.resize(n_p); + w_x.resize(n_p); + w_y.resize(n_p); + desired_v0.resize(n_p); + v_max.resize(n_p); + destination_x.resize(n_p); + destination_y.resize(n_p); + color.resize(n_p); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + float dest_x = BOARD_LENGTH + 30.0; // renamed to avoid shadowing destination_x[] + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + float v_m = 1.3 * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + // Fields the Pedestrian constructor would have zero-initialized (c_v_x=c_v_y=0): + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + float dest_x = -30; + float dest_y = y; + + float init_e_x = dest_x - x; + float init_e_y = dest_y - y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + float v_m = 1.3 * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0f; + w_y[i] = 0.0f; + curr_vel_x[i] = 0.0f; + curr_vel_y[i] = 0.0f; + sb_sq[i] = 0.0f; + sb_e_x[i] = 0.0f; + sb_e_y[i] = 0.0f; + } + + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + (void)pedestrians; +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + // # ADDs: n_iter * ( + // # n_p * 4 + + // # n_p * (n_p - 1) * 14 + + // # n_p * board.n_obstacles * 10 + + // # n_p * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + // # n_p * (n_p - 1) * 24 + + // # n_p * board.n_obstacles * 13 + + // # n_p * 17 + // # ) + + // # DIVs: n_iter * ( + // # n_p * (n_p - 1) + + // # n_p * board.n_obstacles + + // # n_p * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * (n_p - 1) * 3 + + // # n_p * board.n_obstacles + + // # n_p * 3 + // # ) + + // # EXPs: n_iter * ( + // # n_p * (n_p - 1) + + // # n_p * board.n_obstacles + // # ) + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + + float desired_velocity_x = e_x[i] * desired_v0[i]; + float desired_velocity_y = e_y[i] * desired_v0[i]; + float f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; + float f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; + + for (int j = 0; j < n_p; j++) { + if (i == j) + continue; + + float r_ab_x = pos_x[i] - pos_x[j]; + float r_ab_y = pos_y[i] - pos_y[j]; + + float r_ab_norm = sqrt(r_ab_x * r_ab_x + r_ab_y * r_ab_y); + r_ab_norm = r_ab_norm > EPS ? r_ab_norm : EPS; + + float r_ab2_x = r_ab_x - sb_e_x[j]; + float r_ab2_y = r_ab_y - sb_e_y[j]; + + float r_ab2_norm = sqrt(r_ab2_x * r_ab2_x + r_ab2_y * r_ab2_y); + r_ab2_norm = r_ab2_norm > EPS ? r_ab2_norm : EPS; + + float r_ab_norm_sum = r_ab_norm + r_ab2_norm; + + float two_b_sq = r_ab_norm_sum * r_ab_norm_sum - sb_sq[j]; + two_b_sq = two_b_sq > EPS_SQ ? two_b_sq : EPS_SQ; + float two_b = sqrt(two_b_sq); + float scalar_mult_common = (r_ab_norm_sum / (two_b * r_ab_norm * r_ab2_norm)) * (NEG_V0_AB_div_TWO_SIGMA * exp(two_b * NEG_TWO_SIGMA_INV)); + float scalar_mult_r_ab = scalar_mult_common * r_ab2_norm; + float scalar_mult_r_ab2 = scalar_mult_common * r_ab_norm; + + float f_alpha_beta_neg_x = r_ab_x * scalar_mult_r_ab + r_ab2_x * scalar_mult_r_ab2; + float f_alpha_beta_neg_y = r_ab_y * scalar_mult_r_ab + r_ab2_y * scalar_mult_r_ab2; + + float w_val; + + float f_norm_sq = f_alpha_beta_neg_x * f_alpha_beta_neg_x + f_alpha_beta_neg_y * f_alpha_beta_neg_y; + float rhs = f_norm_sq * cos_phi_sq; + float e_dot_f = e_x[i] * f_alpha_beta_neg_x + e_y[i] * f_alpha_beta_neg_y; + float e_dot_f_sq = e_dot_f * e_dot_f; + if (e_dot_f >= 0.0 || e_dot_f_sq <= rhs) + w_val = dt_neg; + else + w_val = c_neg_times_dt; + + f_alpha_dt_x = f_alpha_dt_x + f_alpha_beta_neg_x * w_val; + f_alpha_dt_y = f_alpha_dt_y + f_alpha_beta_neg_y * w_val; + } + + for (int k = 0; k < board.n_obstacles; k++) { + + float v1_x = pos_x[i] - board.obstacles[k].start_x; + float v1_y = pos_y[i] - board.obstacles[k].start_y; + float v2_x = board.obstacles[k].obstacle_v_x; + float v2_y = board.obstacles[k].obstacle_v_y; + + float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + float r_aB_x = pos_x[i] - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + float r_aB_y = pos_y[i] - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; + + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + float f_alpha_B_neg_x = r_aB_x * scalar_mult; + float f_alpha_B_neg_y = r_aB_y * scalar_mult; + + float w_val; + + float e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y[i] : e_y[i]); + + if (e_dot_f >= cos_phi) + w_val = dt_neg; + else + w_val = c_neg_times_dt; + + float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p; i++) { + + float w_norm = sqrt(w_x[i] * w_x[i] + w_y[i] * w_y[i]); + + float w_norm2 = w_norm > EPS ? w_norm : EPS; + + float correction_factor = min(1.0f, v_max[i] / w_norm2); + + curr_vel_x[i] = w_x[i] * correction_factor; + curr_vel_y[i] = w_y[i] * correction_factor; + + pos_x[i] = pos_x[i] + curr_vel_x[i] * dt; + pos_y[i] = pos_y[i] + curr_vel_y[i] * dt; + + if (color[i] == 0 && pos_x[i] > (BOARD_LENGTH - 1.5)) { + pos_x[i] = 1.0; + destination_y[i] = pos_y[i]; + w_x[i] = desired_v0[i]; + w_y[i] = 0.0; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + if (color[i] == 1 && pos_x[i] < 1.5) { + pos_x[i] = BOARD_LENGTH - 1.0; + destination_y[i] = pos_y[i]; + w_x[i] = -desired_v0[i]; + w_y[i] = 0.0; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + + pos_y[i] = clamp(pos_y[i], WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + float ex = destination_x[i] - pos_x[i]; + float ey = destination_y[i] - pos_y[i]; + + float e_norm = sqrt(ex * ex + ey * ey); + float e_norm2 = e_norm > EPS ? e_norm : EPS; + float e_norm_inv = 1.0 / e_norm2; + + e_x[i] = ex * e_norm_inv; + e_y[i] = ey * e_norm_inv; + + float velocity_norm_sq = curr_vel_x[i] * curr_vel_x[i] + curr_vel_y[i] * curr_vel_y[i]; + + float velocity_norm = sqrt(velocity_norm_sq); + + sb_sq[i] = velocity_norm_sq * delta_t_sq; + + sb_e_x[i] = e_x[i] * (velocity_norm * delta_t); + sb_e_y[i] = e_y[i] * (velocity_norm * delta_t); + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_float_inlining_flopcount.cpp b/variants/variant_float_inlining_flopcount.cpp new file mode 100644 index 0000000..482b915 --- /dev/null +++ b/variants/variant_float_inlining_flopcount.cpp @@ -0,0 +1,366 @@ +// # Changes: Replaced «double» with «float» in variable declarations +// # Predecessor: variant_float_baseline.cpp + +#include "../headers/board_reduced_float.hpp" +#include "../headers/constants_float.hpp" +#include "../headers/pedestrian_reduced_float.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0f +#define BOARD_LENGTH 50.0f +#define WALL_EPS 1e-3f +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999f + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + Pedestrian *P = new Pedestrian[n_p]; + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + float x = x_gen_left(gen); + float y = y_gen(gen); + + float start_pos_x = x; + float start_pos_y = y; + + float destination_x = BOARD_LENGTH + 30.0; + float destination_y = y; + + float init_e_x = destination_x - start_pos_x; + float init_e_y = destination_y - start_pos_y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + float v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(0, 0, 0, start_pos_x, start_pos_y, init_e_unit_x, init_e_unit_y, v_max, desired_v0, destination_x, destination_y); + } + + for (int i = n_p_half; i < n_p; i++) { + float x = x_gen_right(gen); + float y = y_gen(gen); + + float start_pos_x = x; + float start_pos_y = y; + float destination_x = -30; + float destination_y = y; + + float init_e_x = destination_x - start_pos_x; + float init_e_y = destination_y - start_pos_y; + float init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + float init_e_unit_x = init_e_x / init_e_norm; + float init_e_unit_y = init_e_y / init_e_norm; + + float desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + float v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(1, 0, 0, start_pos_x, start_pos_y, init_e_unit_x, init_e_unit_y, v_max, desired_v0, destination_x, destination_y); + } + + return P; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + samples.emplace_back(0, i, p.curr_pos_x, p.curr_pos_y, p.e_x, p.e_y, p.color); + } + } +#endif + + // # ADDs: n_iter * ( + // # n_p * 4 + + // # n_p * (n_p - 1) * 14 + + // # n_p * board.n_obstacles * 10 + + // # n_p * 7 + // # ) + + // # MULTs: n_iter * ( + // # n_p * 4 + // # n_p * (n_p - 1) * 24 + + // # n_p * board.n_obstacles * 13 + + // # n_p * 17 + // # ) + + // # DIVs: n_iter * ( + // # n_p * (n_p - 1) + + // # n_p * board.n_obstacles + + // # n_p * 2 + // # ) + + // # SQRTs: n_iter * ( + // # n_p * (n_p - 1) * 3 + + // # n_p * board.n_obstacles + + // # n_p * 3 + // # ) + + // # EXPs: n_iter * ( + // # n_p * (n_p - 1) + + // # n_p * board.n_obstacles + // # ) + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 2 MULTs + float desired_velocity_x = p.e_x * p.desired_v0; + float desired_velocity_y = p.e_y * p.desired_v0; + + // # 2 MULTs, 2 ADDs + float f_alpha_dt_x = (desired_velocity_x - p.curr_vel_x) * dt_times_tau_alpha_inv; + float f_alpha_dt_y = (desired_velocity_y - p.curr_vel_y) * dt_times_tau_alpha_inv; + + for (int j = 0; j < n_p; j++) { + if (i == j) + continue; + + // # 2 ADDs + float r_ab_x = p.curr_pos_x - pedestrians[j].curr_pos_x; + float r_ab_y = p.curr_pos_y - pedestrians[j].curr_pos_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_ab_norm = sqrt(r_ab_x * r_ab_x + r_ab_y * r_ab_y); + r_ab_norm = r_ab_norm > EPS ? r_ab_norm : EPS; + + // # 2 ADDs + float r_ab2_x = r_ab_x - pedestrians[j].s_b_e_x; + float r_ab2_y = r_ab_y - pedestrians[j].s_b_e_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_ab2_norm = sqrt(r_ab2_x * r_ab2_x + r_ab2_y * r_ab2_y); + r_ab2_norm = r_ab2_norm > EPS ? r_ab2_norm : EPS; + + // # 1 ADD + float r_ab_norm_sum = r_ab_norm + r_ab2_norm; + + // # 1 MULT 1 ADD + float two_b_sq = r_ab_norm_sum * r_ab_norm_sum - pedestrians[j].s_b_sq; + two_b_sq = two_b_sq > EPS_SQ ? two_b_sq : EPS_SQ; + + // # 1 SQRT + float two_b = sqrt(two_b_sq); + + // # 5 MULTs, 1 DIV, 1 EXP + float scalar_mult_common = (r_ab_norm_sum / (two_b * r_ab_norm * r_ab2_norm)) * (NEG_V0_AB_div_TWO_SIGMA * exp(two_b * NEG_TWO_SIGMA_INV)); + + // # 2 MULTs + float scalar_mult_r_ab = scalar_mult_common * r_ab2_norm; + float scalar_mult_r_ab2 = scalar_mult_common * r_ab_norm; + + // # 4 MULTs, 2 ADDs + float f_alpha_beta_neg_x = r_ab_x * scalar_mult_r_ab + r_ab2_x * scalar_mult_r_ab2; + float f_alpha_beta_neg_y = r_ab_y * scalar_mult_r_ab + r_ab2_y * scalar_mult_r_ab2; + + float w_val; + + // # 6 MULTs, 2 ADDs + float f_norm_sq = f_alpha_beta_neg_x * f_alpha_beta_neg_x + f_alpha_beta_neg_y * f_alpha_beta_neg_y; + float rhs = f_norm_sq * cos_phi_sq; + float e_dot_f = p.e_x * f_alpha_beta_neg_x + p.e_y * f_alpha_beta_neg_y; + float e_dot_f_sq = e_dot_f * e_dot_f; + + if (e_dot_f >= 0.0 || e_dot_f_sq <= rhs) + w_val = dt_neg; + else + w_val = c_neg_times_dt; + + // # 2 MULTs, 2 ADDs + f_alpha_dt_x = f_alpha_dt_x + f_alpha_beta_neg_x * w_val; + f_alpha_dt_y = f_alpha_dt_y + f_alpha_beta_neg_y * w_val; + } + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + float v1_x = p.curr_pos_x - board.obstacles[k].start_x; + float v1_y = p.curr_pos_y - board.obstacles[k].start_y; + float v2_x = board.obstacles[k].obstacle_v_x; + float v2_y = board.obstacles[k].obstacle_v_y; + + // # 3 MULTs, 1 ADD + float projection = (v1_x * v2_x + v1_y * v2_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + // # 4 ADDs, 2 MULTs + float r_aB_x = p.curr_pos_x - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + float r_aB_y = p.curr_pos_y - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + float r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + r_aB_norm = r_aB_norm > EPS ? r_aB_norm : EPS; + + // # 4 MULTs, 1 EXP, 1 DIV + float scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + float f_alpha_B_neg_x = r_aB_x * scalar_mult; + float f_alpha_B_neg_y = r_aB_y * scalar_mult; + + float w_val; + + float e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -p.e_y : p.e_y); + + if (e_dot_f >= cos_phi) + w_val = dt_neg; + else + w_val = c_neg_times_dt; + + // # 2 MULTS + float f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + float f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + p.w_x += f_alpha_dt_x; + p.w_y += f_alpha_dt_y; + } + + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 1 SQRT, 2 MULTs, 1 ADD + float w_norm = sqrt(p.w_x * p.w_x + p.w_y * p.w_y); + + float w_norm2 = w_norm > EPS ? w_norm : EPS; + + // # 1 DIV + float correction_factor = min(1.0f, p.v_max / w_norm2); + + // # 2 MULTs + p.curr_vel_x = p.w_x * correction_factor; + p.curr_vel_y = p.w_y * correction_factor; + + // # 2 MULTs, 2 ADDs + p.curr_pos_x = p.curr_pos_x + p.curr_vel_x * dt; + p.curr_pos_y = p.curr_pos_y + p.curr_vel_y * dt; + + if (p.color == 0 && p.curr_pos_x > (BOARD_LENGTH - 1.5)) { + p.curr_pos_x = 1.0; + p.destination_y = p.curr_pos_y; + p.w_x = p.desired_v0; + p.w_y = 0.0; + p.curr_vel_x = p.w_x; + p.curr_vel_y = p.w_y; + } + if (p.color == 1 && p.curr_pos_x < 1.5) { + p.curr_pos_x = BOARD_LENGTH - 1.0; + p.destination_y = p.curr_pos_y; + p.w_x = -p.desired_v0; + p.w_y = 0.0; + p.curr_vel_x = p.w_x; + p.curr_vel_y = p.w_y; + } + + p.curr_pos_y = clamp(p.curr_pos_y, WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + // # 2 ADDs + float e_x = p.destination_x - p.curr_pos_x; + float e_y = p.destination_y - p.curr_pos_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + float e_norm = sqrt(e_x * e_x + e_y * e_y); + + float e_norm2 = e_norm > EPS ? e_norm : EPS; + + // # 1 DIV + float e_norm_inv = 1.0 / e_norm2; + + // # 2 MULTs + p.e_x = e_x * e_norm_inv; + p.e_y = e_y * e_norm_inv; + + // # 2 MULTs, 1 ADD + float velocity_norm_sq = p.curr_vel_x * p.curr_vel_x + p.curr_vel_y * p.curr_vel_y; + + // # 1 SQRT + float velocity_norm = sqrt(velocity_norm_sq); + + // # 5 MULTs + p.s_b_sq = velocity_norm_sq * delta_t_sq; + p.s_b_e_x = p.e_x * (velocity_norm * delta_t); + p.s_b_e_y = p.e_y * (velocity_norm * delta_t); + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, p.curr_pos_x, p.curr_pos_y, p.e_x, p.e_y, p.color); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_inlining_7_SoA_AVX2_polyexp_expfix.cpp b/variants/variant_inlining_7_SoA_AVX2_polyexp_expfix.cpp index 36fef1a..a5c93b8 100644 --- a/variants/variant_inlining_7_SoA_AVX2_polyexp_expfix.cpp +++ b/variants/variant_inlining_7_SoA_AVX2_polyexp_expfix.cpp @@ -190,21 +190,23 @@ static inline __m256d exp256_pd(__m256d x) { const __m256d ln2 = _mm256_set1_pd(0.6931471805599453); __m256d r = _mm256_fnmadd_pd(nf, ln2, x); // # 4 MULTs, 4 ADDs - const __m256d c12 = _mm256_set1_pd(1.0 / 479001600.0); - const __m256d c11 = _mm256_set1_pd(1.0 / 39916800.0); - const __m256d c10 = _mm256_set1_pd(1.0 / 3628800.0); - const __m256d c9 = _mm256_set1_pd(1.0 / 362880.0); - const __m256d c8 = _mm256_set1_pd(1.0 / 40320.0); - const __m256d c7 = _mm256_set1_pd(1.0 / 5040.0); - const __m256d c6 = _mm256_set1_pd(1.0 / 720.0); - const __m256d c5 = _mm256_set1_pd(1.0 / 120.0); - const __m256d c4 = _mm256_set1_pd(1.0 / 24.0); - const __m256d c3 = _mm256_set1_pd(1.0 / 6.0); - const __m256d c2 = _mm256_set1_pd(0.5); - const __m256d c1 = _mm256_set1_pd(1.0); - const __m256d c0 = _mm256_set1_pd(1.0); + const __m256d c13 = _mm256_set1_pd(c13_scalar); + const __m256d c12 = _mm256_set1_pd(c12_scalar); + const __m256d c11 = _mm256_set1_pd(c11_scalar); + const __m256d c10 = _mm256_set1_pd(c10_scalar); + const __m256d c9 = _mm256_set1_pd(c9_scalar); + const __m256d c8 = _mm256_set1_pd(c8_scalar); + const __m256d c7 = _mm256_set1_pd(c7_scalar); + const __m256d c6 = _mm256_set1_pd(c6_scalar); + const __m256d c5 = _mm256_set1_pd(c5_scalar); + const __m256d c4 = _mm256_set1_pd(c4_scalar); + const __m256d c3 = _mm256_set1_pd(c3_scalar); + const __m256d c2 = _mm256_set1_pd(c2_scalar); + const __m256d c1 = _mm256_set1_pd(c1_scalar); + const __m256d c0 = _mm256_set1_pd(c0_scalar); + + __m256d p = c13; - __m256d p = c12; // # 13 * (4 MULTs, 4 ADDs) // # = 52 MULTs, 52 ADDs p = _mm256_fmadd_pd(p, r, c12); diff --git a/variants/variant_inlining_7_SoA_flopcount.cpp b/variants/variant_inlining_7_SoA_flopcount.cpp new file mode 100644 index 0000000..8c10a6a --- /dev/null +++ b/variants/variant_inlining_7_SoA_flopcount.cpp @@ -0,0 +1,362 @@ +// # This file uses avx2 +// # This is the first variant and should serve as a base for further avx2 optimizations + +// Okay our first step is to use a SoA instead of an AoS +// We only do SoA for the pedestrian struct, there we wanna optimize such that we access for the ped-ped forces adjacent pedestrians (in the arrays) + +#include "../headers/board.hpp" +#include "../headers/constants.hpp" +#include "../headers/pedestrian_reduced.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0 +#define BOARD_LENGTH 50.0 +#define WALL_EPS 1e-3 +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999 + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +// we wanna use arrays so we can implement SOA, we create arrays for all the data we need and access +vector pos_x, pos_y; +vector sb_sq; +vector sb_e_x, sb_e_y; +vector e_x, e_y; +vector curr_vel_x, curr_vel_y; +vector w_x, w_y; +vector desired_v0; +vector v_max; +vector destination_x, destination_y; +vector color; + +Pedestrian *init_pedestrians(int n_p) { + +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + // resize all our arrays for this run + pos_x.resize(n_p); + pos_y.resize(n_p); + sb_sq.resize(n_p); + sb_e_x.resize(n_p); + sb_e_y.resize(n_p); + e_x.resize(n_p); + e_y.resize(n_p); + curr_vel_x.resize(n_p); + curr_vel_y.resize(n_p); + w_x.resize(n_p); + w_y.resize(n_p); + desired_v0.resize(n_p); + v_max.resize(n_p); + destination_x.resize(n_p); + destination_y.resize(n_p); + color.resize(n_p); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + double x = x_gen_left(gen); + double y = y_gen(gen); + + double dest_x = BOARD_LENGTH + 30.0; // renamed to avoid shadowing destination_x[] + double dest_y = y; // same idea for destination_y[] + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + // Fields the Pedestrian constructor would have zero-initialized: + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + for (int i = n_p_half; i < n_p; i++) { + double x = x_gen_right(gen); + double y = y_gen(gen); + + double dest_x = -30; + double dest_y = y; + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + // Fields the Pedestrian constructor would have zero-initialized: + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + // Pedestrian &p = pedestrians[i]; + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + // # ADDs: n_iter * n_p * 11 + + // # n_iter * n_p * (n_p - 1) * 14 + + // # n_iter * n_p * board.n_obstacles * 12 + + // # MULTs: n_iter * n_p * 21 + + // # n_iter * n_p * (n_p - 1) * 24 + + // # n_iter * n_p * board.n_obstacles * 19 + + // # DIVs: n_iter * n_p * 2 + + // # n_iter * n_p * (n_p - 1) + + // # n_iter * n_p * board.n_obstacles + + // # SQRTs: n_iter * n_p * 3 + + // # n_iter * n_p * (n_p - 1) * 3 + + // # n_iter * n_p * board.n_obstacles + + // # EXPs: n_iter * n_p * (n_p - 1) + + // # n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + + for (int i = 0; i < n_p; i++) { + + double desired_velocity_x = e_x[i] * desired_v0[i]; + double desired_velocity_y = e_y[i] * desired_v0[i]; + + double f_alpha_dt_x = (desired_velocity_x - curr_vel_x[i]) * dt_times_tau_alpha_inv; + double f_alpha_dt_y = (desired_velocity_y - curr_vel_y[i]) * dt_times_tau_alpha_inv; + + for (int j = 0; j < n_p; j++) { + + if (i == j) + continue; + + double r_ab_x = pos_x[i] - pos_x[j]; + double r_ab_y = pos_y[i] - pos_y[j]; + + double r_ab_norm = sqrt(r_ab_x * r_ab_x + r_ab_y * r_ab_y); + + double r_ab2_x = r_ab_x - sb_e_x[j]; + double r_ab2_y = r_ab_y - sb_e_y[j]; + + double r_ab2_norm = sqrt(r_ab2_x * r_ab2_x + r_ab2_y * r_ab2_y); + double r_ab_norm_sum = r_ab_norm + r_ab2_norm; + double two_b_sq = r_ab_norm_sum * r_ab_norm_sum - sb_sq[j]; + double two_b = sqrt(two_b_sq); + double scalar_mult_common = (r_ab_norm_sum / (two_b * r_ab_norm * r_ab2_norm)) * (NEG_V0_AB_div_TWO_SIGMA * exp(two_b * NEG_TWO_SIGMA_INV)); + double scalar_mult_r_ab = scalar_mult_common * r_ab2_norm; + double scalar_mult_r_ab2 = scalar_mult_common * r_ab_norm; + + double f_alpha_beta_neg_x = r_ab_x * scalar_mult_r_ab + r_ab2_x * scalar_mult_r_ab2; + double f_alpha_beta_neg_y = r_ab_y * scalar_mult_r_ab + r_ab2_y * scalar_mult_r_ab2; + + double w_val; + double a = (e_x[i] * f_alpha_beta_neg_x + e_y[i] * f_alpha_beta_neg_y) * cos_phi_inv; + double b_sq = f_alpha_beta_neg_x * f_alpha_beta_neg_x + f_alpha_beta_neg_y * f_alpha_beta_neg_y; + + w_val = dt_neg; + if (a >= 0 && (a * a > b_sq)) { + w_val = c_neg_times_dt; + } + + f_alpha_dt_x = f_alpha_dt_x + f_alpha_beta_neg_x * w_val; + f_alpha_dt_y = f_alpha_dt_y + f_alpha_beta_neg_y * w_val; + } + + for (int k = 0; k < board.n_obstacles; k++) { + + double v1_x = pos_x[i] - board.obstacles[k].start.x; + double v1_y = pos_y[i] - board.obstacles[k].start.y; + + double projection = (v1_x * board.obstacles[k].obstacle_v.x + v1_y * board.obstacles[k].obstacle_v.y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + double r_aB_x = pos_x[i] - (board.obstacles[k].start.x + board.obstacles[k].obstacle_v.x * projection); + double r_aB_y = pos_y[i] - (board.obstacles[k].start.y + board.obstacles[k].obstacle_v.y * projection); + + double r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + double scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + double f_alpha_B_neg_x = r_aB_x * scalar_mult; + double f_alpha_B_neg_y = r_aB_y * scalar_mult; + + double w_val; + double a = (e_x[i] * f_alpha_B_neg_x + e_y[i] * f_alpha_B_neg_y) * cos_phi_inv; + double b_sq = f_alpha_B_neg_x * f_alpha_B_neg_x + f_alpha_B_neg_y * f_alpha_B_neg_y; + + w_val = dt_neg; + if (a >= 0 && (a * a > b_sq)) { + w_val = c_neg_times_dt; + } + + double f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + double f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p; i++) { + + double w_norm = sqrt(w_x[i] * w_x[i] + w_y[i] * w_y[i]); + + double correction_factor = min(1.0, v_max[i] / w_norm); + + curr_vel_x[i] = w_x[i] * correction_factor; + curr_vel_y[i] = w_y[i] * correction_factor; + + pos_x[i] = pos_x[i] + curr_vel_x[i] * dt; + pos_y[i] = pos_y[i] + curr_vel_y[i] * dt; + + if (color[i] == 0 && pos_x[i] > (BOARD_LENGTH - 1.5)) { + pos_x[i] = 1.0; + destination_y[i] = pos_y[i]; + w_x[i] = desired_v0[i]; + w_y[i] = 0.0; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + if (color[i] == 1 && pos_x[i] < 1.5) { + pos_x[i] = BOARD_LENGTH - 1.0; + destination_y[i] = pos_y[i]; + w_x[i] = -desired_v0[i]; + w_y[i] = 0.0; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + + pos_y[i] = clamp(pos_y[i], WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + double ex = destination_x[i] - pos_x[i]; + double ey = destination_y[i] - pos_y[i]; + + double e_norm_inv = 1.0 / sqrt(ex * ex + ey * ey); + + e_x[i] = ex * e_norm_inv; + e_y[i] = ey * e_norm_inv; + + double velocity_norm_sq = curr_vel_x[i] * curr_vel_x[i] + curr_vel_y[i] * curr_vel_y[i]; + + double velocity_norm = sqrt(velocity_norm_sq); + + sb_sq[i] = velocity_norm_sq * delta_t_sq; + + sb_e_x[i] = e_x[i] * (velocity_norm * delta_t); + sb_e_y[i] = e_y[i] * (velocity_norm * delta_t); + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_inlining_7_flopcount.cpp b/variants/variant_inlining_7_flopcount.cpp new file mode 100644 index 0000000..9e5b28a --- /dev/null +++ b/variants/variant_inlining_7_flopcount.cpp @@ -0,0 +1,352 @@ +// # This file performs in-lining for run_simulation. +// # Changes: Removed 2 sqrt() calls from the loop bodies +// # Predecessor: variant_inlining_6.cpp + +#include "../headers/board.hpp" +#include "../headers/constants.hpp" +#include "../headers/pedestrian_reduced.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0 +#define BOARD_LENGTH 50.0 +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0 +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5 +#define WALL_EPS 1e-3 +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999 + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + Pedestrian *P = new Pedestrian[n_p]; + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + double x = x_gen_left(gen); + double y = y_gen(gen); + + double start_pos_x = x; + double start_pos_y = y; + + double destination_x = BOARD_LENGTH + 30.0; + double destination_y = y; + + double init_e_x = destination_x - start_pos_x; + double init_e_y = destination_y - start_pos_y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + double v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(0, 0, 0, start_pos_x, start_pos_y, init_e_unit_x, init_e_unit_y, v_max, desired_v0, destination_x, destination_y); + } + + for (int i = n_p_half; i < n_p; i++) { + double x = x_gen_right(gen); + double y = y_gen(gen); + + double start_pos_x = x; + double start_pos_y = y; + double destination_x = -30; + double destination_y = y; + + double init_e_x = destination_x - start_pos_x; + double init_e_y = destination_y - start_pos_y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + double v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(1, 0, 0, start_pos_x, start_pos_y, init_e_unit_x, init_e_unit_y, v_max, desired_v0, destination_x, destination_y); + } + + return P; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + samples.emplace_back(0, i, p.curr_pos_x, p.curr_pos_y, p.e_x, p.e_y, p.color); + } + } +#endif + + // # ADDs: n_iter * n_p * 11 + + // # n_iter * n_p * (n_p - 1) * 14 + + // # n_iter * n_p * board.n_obstacles * 12 + + // # MULTs: n_iter * n_p * 21 + + // # n_iter * n_p * (n_p - 1) * 24 + + // # n_iter * n_p * board.n_obstacles * 19 + + // # DIVs: n_iter * n_p * 2 + + // # n_iter * n_p * (n_p - 1) + + // # n_iter * n_p * board.n_obstacles + + // # SQRTs: n_iter * n_p * 3 + + // # n_iter * n_p * (n_p - 1) * 3 + + // # n_iter * n_p * board.n_obstacles + + // # EXPs: n_iter * n_p * (n_p - 1) + + // # n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 2 MULTs + double desired_velocity_x = p.e_x * p.desired_v0; + double desired_velocity_y = p.e_y * p.desired_v0; + + // # 2 MULTs, 2 ADDs + double f_alpha_dt_x = (desired_velocity_x - p.curr_vel_x) * dt_times_tau_alpha_inv; + double f_alpha_dt_y = (desired_velocity_y - p.curr_vel_y) * dt_times_tau_alpha_inv; + + for (int j = 0; j < n_p; j++) { + if (i == j) + continue; + + // # 2 ADDs + double r_ab_x = p.curr_pos_x - pedestrians[j].curr_pos_x; + double r_ab_y = p.curr_pos_y - pedestrians[j].curr_pos_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_ab_norm = sqrt(r_ab_x * r_ab_x + r_ab_y * r_ab_y); + + // # 2 ADDs + double r_ab2_x = r_ab_x - pedestrians[j].s_b_e_x; + double r_ab2_y = r_ab_y - pedestrians[j].s_b_e_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_ab2_norm = sqrt(r_ab2_x * r_ab2_x + r_ab2_y * r_ab2_y); + + // # 1ADD + double r_ab_norm_sum = r_ab_norm + r_ab2_norm; + + // # 1 MULT, 1 ADD + double two_b_sq = r_ab_norm_sum * r_ab_norm_sum - pedestrians[j].s_b_sq; + + // # 1 SQRT + double two_b = sqrt(two_b_sq); + + // # 5 MULTs, 1 EXP, 1 DIV + double scalar_mult_common = (r_ab_norm_sum / (two_b * r_ab_norm * r_ab2_norm)) * (NEG_V0_AB_div_TWO_SIGMA * exp(two_b * NEG_TWO_SIGMA_INV)); + + // # 2 MULTs + double scalar_mult_r_ab = scalar_mult_common * r_ab2_norm; + double scalar_mult_r_ab2 = scalar_mult_common * r_ab_norm; + + // # 4 MULTs, 2 ADDs + double f_alpha_beta_neg_x = r_ab_x * scalar_mult_r_ab + r_ab2_x * scalar_mult_r_ab2; + double f_alpha_beta_neg_y = r_ab_y * scalar_mult_r_ab + r_ab2_y * scalar_mult_r_ab2; + + double w_val; + + // # 3 MULTs, 1 ADD + double a = (p.e_x * f_alpha_beta_neg_x + p.e_y * f_alpha_beta_neg_y) * cos_phi_inv; + + // # 2 MULTs, 1 ADD + double b_sq = f_alpha_beta_neg_x * f_alpha_beta_neg_x + f_alpha_beta_neg_y * f_alpha_beta_neg_y; + + w_val = dt_neg; + + // # 1 MULT + if (a >= 0 && (a * a > b_sq)) { + w_val = c_neg_times_dt; + } + + // # 2 MULTs, 2 ADDs + f_alpha_dt_x = f_alpha_dt_x + f_alpha_beta_neg_x * w_val; + f_alpha_dt_y = f_alpha_dt_y + f_alpha_beta_neg_y * w_val; + } + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + double v1_x = p.curr_pos_x - board.obstacles[k].start.x; + double v1_y = p.curr_pos_y - board.obstacles[k].start.y; + + // # 3 MULTs, 1 ADD + double projection = (v1_x * board.obstacles[k].obstacle_v.x + v1_y * board.obstacles[k].obstacle_v.y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + // # 4 ADDs, 2 MULTs + double r_aB_x = p.curr_pos_x - (board.obstacles[k].start.x + board.obstacles[k].obstacle_v.x * projection); + double r_aB_y = p.curr_pos_y - (board.obstacles[k].start.y + board.obstacles[k].obstacle_v.y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + + // # 4 MULTs, 1 EXP, 1 DIV + double scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + double f_alpha_B_neg_x = r_aB_x * scalar_mult; + double f_alpha_B_neg_y = r_aB_y * scalar_mult; + + double w_val; + + // # 3 MULTs, 1 ADD + double a = (p.e_x * f_alpha_B_neg_x + p.e_y * f_alpha_B_neg_y) * cos_phi_inv; + + // # 2 MULTS, 1 ADD + double b_sq = f_alpha_B_neg_x * f_alpha_B_neg_x + f_alpha_B_neg_y * f_alpha_B_neg_y; + + w_val = dt_neg; + + // # 1 MULT + if (a >= 0 && (a * a > b_sq)) { + w_val = c_neg_times_dt; + } + + // # 2 MULTs + double f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + double f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + p.w_x += f_alpha_dt_x; + p.w_y += f_alpha_dt_y; + } + + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 1 SQRT, 2 MULTs, 1 ADD + double w_norm = sqrt(p.w_x * p.w_x + p.w_y * p.w_y); + + // # 1 DIV + double correction_factor = min(1.0, p.v_max / w_norm); + + // # 2 MULTs + p.curr_vel_x = p.w_x * correction_factor; + p.curr_vel_y = p.w_y * correction_factor; + + // # 2 MULTs, 2 ADDs + p.curr_pos_x = p.curr_pos_x + p.curr_vel_x * dt; + p.curr_pos_y = p.curr_pos_y + p.curr_vel_y * dt; + + if (p.color == 0 && p.curr_pos_x > BOARD_LENGTH_MINUS_ONE_POINT_FIVE) { + p.curr_pos_x = 1.0; + p.destination_y = p.curr_pos_y; + p.w_x = p.desired_v0; + p.w_y = 0.0; + p.curr_vel_x = p.w_x; + p.curr_vel_y = p.w_y; + } + if (p.color == 1 && p.curr_pos_x < 1.5) { + p.curr_pos_x = BOARD_LENGTH_MINUS_ONE; + p.destination_y = p.curr_pos_y; + p.w_x = -p.desired_v0; + p.w_y = 0.0; + p.curr_vel_x = p.w_x; + p.curr_vel_y = p.w_y; + } + + p.curr_pos_y = clamp(p.curr_pos_y, WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + // # 2 ADDs + double e_x = p.destination_x - p.curr_pos_x; + double e_y = p.destination_y - p.curr_pos_y; + + // # 1 DIV, 1 SQRT, 2 MULTs, 1 ADD + double e_norm_inv = 1.0 / sqrt(e_x * e_x + e_y * e_y); + + // # 2 MULTs + p.e_x = e_x * e_norm_inv; + p.e_y = e_y * e_norm_inv; + + // # 2 MULTs, 1 ADD + double velocity_norm_sq = p.curr_vel_x * p.curr_vel_x + p.curr_vel_y * p.curr_vel_y; + + // # 1 SQRT + double velocity_norm = sqrt(velocity_norm_sq); + + // # 5 MULTs + p.s_b_sq = velocity_norm_sq * delta_t_sq; + p.s_b_e_x = p.e_x * (velocity_norm * delta_t); + p.s_b_e_y = p.e_y * (velocity_norm * delta_t); + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, p.curr_pos_x, p.curr_pos_y, p.e_x, p.e_y, p.color); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp b/variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp new file mode 100644 index 0000000..cb3d8e3 --- /dev/null +++ b/variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_expfix.cpp @@ -0,0 +1,483 @@ +// # Changes: +// # - Ported AVX2 to AVX-512 +// # - Replaced Obstacle with the version that contains no Vector2d +// # - Implemented Fast Inverse Square Root +// # Predecessor: variant_inlining_7_SoA_AVX2_polyexp.cpp + +#include "../headers/board_reduced.hpp" +#include "../headers/constants.hpp" +#include "../headers/pedestrian_reduced.hpp" + +#include + +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0 +#define BOARD_LENGTH 50.0 +#define WALL_EPS 1e-3 +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999 + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { + +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 7) & ~7; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + double x = x_gen_left(gen); + double y = y_gen(gen); + + double dest_x = BOARD_LENGTH + 30.0; + double dest_y = y; + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + for (int i = n_p_half; i < n_p; i++) { + double x = x_gen_right(gen); + double y = y_gen(gen); + + double dest_x = -30; + double dest_y = y; + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9; + pos_y[j] = 1e9; + sb_sq[j] = 0.0; + sb_e_x[j] = 0.0; + sb_e_y[j] = 0.0; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 128 MULTs, 112 ADDs +static inline __m512d _avx512_exp_pd(__m512d x) { + + const __m512d log2e = _mm512_set1_pd(1.4426950408889634); + + // # 8 MULTs + __m512d nf = _mm512_roundscale_pd(_mm512_mul_pd(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + const __m512d ln2 = _mm512_set1_pd(0.6931471805599453); + + // # 8 MULTs, 8 ADDs + __m512d r = _mm512_fnmadd_pd(nf, ln2, x); + + const __m512d c13 = _mm512_set1_pd(c13_scalar); + const __m512d c12 = _mm512_set1_pd(c12_scalar); + const __m512d c11 = _mm512_set1_pd(c11_scalar); + const __m512d c10 = _mm512_set1_pd(c10_scalar); + const __m512d c9 = _mm512_set1_pd(c9_scalar); + const __m512d c8 = _mm512_set1_pd(c8_scalar); + const __m512d c7 = _mm512_set1_pd(c7_scalar); + const __m512d c6 = _mm512_set1_pd(c6_scalar); + const __m512d c5 = _mm512_set1_pd(c5_scalar); + const __m512d c4 = _mm512_set1_pd(c4_scalar); + const __m512d c3 = _mm512_set1_pd(c3_scalar); + const __m512d c2 = _mm512_set1_pd(c2_scalar); + const __m512d c1 = _mm512_set1_pd(c1_scalar); + const __m512d c0 = _mm512_set1_pd(c0_scalar); + + __m512d p = c13; + + // # 104 MULTs, 104 ADDs + p = _mm512_fmadd_pd(p, r, c12); + p = _mm512_fmadd_pd(p, r, c11); + p = _mm512_fmadd_pd(p, r, c10); + p = _mm512_fmadd_pd(p, r, c9); + p = _mm512_fmadd_pd(p, r, c8); + p = _mm512_fmadd_pd(p, r, c7); + p = _mm512_fmadd_pd(p, r, c6); + p = _mm512_fmadd_pd(p, r, c5); + p = _mm512_fmadd_pd(p, r, c4); + p = _mm512_fmadd_pd(p, r, c3); + p = _mm512_fmadd_pd(p, r, c2); + p = _mm512_fmadd_pd(p, r, c1); + p = _mm512_fmadd_pd(p, r, c0); + + __m256d nf_lo = _mm512_castpd512_pd256(nf); + __m256d nf_hi = _mm512_extractf64x4_pd(nf, 1); + + __m128i ni32_lo = _mm256_cvtpd_epi32(nf_lo); + __m128i ni32_hi = _mm256_cvtpd_epi32(nf_hi); + + __m256i ni64_lo = _mm256_cvtepi32_epi64(ni32_lo); + __m256i ni64_hi = _mm256_cvtepi32_epi64(ni32_hi); + + __m512i ni64 = _mm512_inserti64x4(_mm512_castsi256_si512(ni64_lo), ni64_hi, 1); + + __m512i biased = _mm512_add_epi64(ni64, _mm512_set1_epi64(1023)); + + __m512i scaled = _mm512_slli_epi64(biased, 52); + + __m512d pow2n = _mm512_castsi512_pd(scaled); + + // # 8 MULTs + return _mm512_mul_pd(p, pow2n); +} + +static inline double fast_inv_sqrt(double number) { + double y = number; + + uint64_t i = bit_cast(y); + + i = 0x5fe6eb50c7b537a9ULL - (i >> 1); + + y = bit_cast(i); + + double x2 = number * 0.5; + y = y * (1.5 - (x2 * y * y)); + y = y * (1.5 - (x2 * y * y)); + y = y * (1.5 - (x2 * y * y)); + + return y; +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 7) & ~7; + + alignas(64) constexpr double lane_offset_arr[8] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; + const __m512d lane_off = _mm512_load_pd(lane_offset_arr); + const __m512d v_neg_v0_div_2s = _mm512_set1_pd(NEG_V0_AB_div_TWO_SIGMA); + const __m512d v_neg_2s_inv = _mm512_set1_pd(NEG_TWO_SIGMA_INV); + const __m512d v_cos_phi_inv = _mm512_set1_pd(cos_phi_inv); + const __m512d v_dt_neg = _mm512_set1_pd(dt_neg); + const __m512d v_c_neg_dt = _mm512_set1_pd(c_neg_times_dt); + const __m512d v_zero = _mm512_setzero_pd(); + + const __m512d v_np = _mm512_set1_pd(n_p); + + // # ADDs: n_iter * n_p * 33 + + // # n_iter * n_p * (n_p_pad / 8) * 232 + + // # n_iter * n_p * board.n_obstacles * 10 + + // # MULTs: n_iter * n_p * 40 + + // # n_iter * n_p * (n_p_pad / 8) * 320 + + // # n_iter * n_p * board.n_obstacles * 13 + + // # DIVs: n_iter * n_p * (n_p_pad / 8) * 8 + + // # n_iter * n_p * board.n_obstacles + + // # SQRTs: n_iter * n_p + + // # n_iter * n_p * (n_p_pad / 8) * 24 + + // # n_iter * n_p * board.n_obstacles + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + + for (int i = 0; i < n_p; i++) { + double pos_x_i = pos_x[i]; + double pos_y_i = pos_y[i]; + double e_x_i = e_x[i]; + double e_y_i = e_y[i]; + double desired_v0_i = desired_v0[i]; + double curr_vel_x_i = curr_vel_x[i]; + double curr_vel_y_i = curr_vel_y[i]; + + double f_alpha_dt_x = (e_x_i * desired_v0_i - curr_vel_x_i) * dt_times_tau_alpha_inv; + double f_alpha_dt_y = (e_y_i * desired_v0_i - curr_vel_y_i) * dt_times_tau_alpha_inv; + + const __m512d pix = _mm512_set1_pd(pos_x_i); + const __m512d piy = _mm512_set1_pd(pos_y_i); + const __m512d eix = _mm512_set1_pd(e_x_i); + const __m512d eiy = _mm512_set1_pd(e_y_i); + const __m512d v_i = _mm512_set1_pd((double)i); + + __m512d acc_x = _mm512_setzero_pd(); + __m512d acc_y = _mm512_setzero_pd(); + + for (int j = 0; j < n_p_pad; j += 8) { + __m512d j_idx = _mm512_add_pd(_mm512_set1_pd((double)j), lane_off); + + __mmask8 m_neq_i = _mm512_cmp_pd_mask(j_idx, v_i, _CMP_NEQ_OQ); + __mmask8 m_in_range = _mm512_cmp_pd_mask(j_idx, v_np, _CMP_LT_OQ); + __mmask8 active = m_neq_i & m_in_range; + + __m512d pjx = _mm512_loadu_pd(&pos_x[j]); + __m512d pjy = _mm512_loadu_pd(&pos_y[j]); + __m512d sbe_jx = _mm512_loadu_pd(&sb_e_x[j]); + __m512d sbe_jy = _mm512_loadu_pd(&sb_e_y[j]); + __m512d sb_jsq = _mm512_loadu_pd(&sb_sq[j]); + + __m512d r_ab_x = _mm512_sub_pd(pix, pjx); + __m512d r_ab_y = _mm512_sub_pd(piy, pjy); + __m512d r_ab_n2 = _mm512_fmadd_pd(r_ab_x, r_ab_x, _mm512_mul_pd(r_ab_y, r_ab_y)); + __m512d r_ab_n = _mm512_sqrt_pd(r_ab_n2); + + __m512d r_ab2_x = _mm512_sub_pd(r_ab_x, sbe_jx); + __m512d r_ab2_y = _mm512_sub_pd(r_ab_y, sbe_jy); + __m512d r_ab2_n2 = _mm512_fmadd_pd(r_ab2_x, r_ab2_x, _mm512_mul_pd(r_ab2_y, r_ab2_y)); + __m512d r_ab2_n = _mm512_sqrt_pd(r_ab2_n2); + + __m512d r_sum = _mm512_add_pd(r_ab_n, r_ab2_n); + __m512d two_b_sq = _mm512_fmsub_pd(r_sum, r_sum, sb_jsq); + __m512d two_b = _mm512_sqrt_pd(two_b_sq); + + __m512d e_arg = _mm512_mul_pd(two_b, v_neg_2s_inv); + __m512d e_val = _avx512_exp_pd(e_arg); + + __m512d numer = _mm512_mul_pd(_mm512_mul_pd(r_sum, v_neg_v0_div_2s), e_val); + __m512d denom = _mm512_mul_pd(_mm512_mul_pd(two_b, r_ab_n), r_ab2_n); + __m512d denom_safe = _mm512_mask_blend_pd(active, _mm512_set1_pd(1.0), denom); + __m512d smc = _mm512_div_pd(numer, denom_safe); + + __m512d sm_r_ab = _mm512_mul_pd(smc, r_ab2_n); + __m512d sm_r_ab2 = _mm512_mul_pd(smc, r_ab_n); + + __m512d f_x = _mm512_fmadd_pd(r_ab2_x, sm_r_ab2, _mm512_mul_pd(r_ab_x, sm_r_ab)); + __m512d f_y = _mm512_fmadd_pd(r_ab2_y, sm_r_ab2, _mm512_mul_pd(r_ab_y, sm_r_ab)); + + __m512d a = _mm512_mul_pd(_mm512_fmadd_pd(eix, f_x, _mm512_mul_pd(eiy, f_y)), v_cos_phi_inv); + __m512d a_sq = _mm512_mul_pd(a, a); + __m512d b_sq = _mm512_fmadd_pd(f_x, f_x, _mm512_mul_pd(f_y, f_y)); + + __mmask8 k_ge = _mm512_cmp_pd_mask(a, v_zero, _CMP_GE_OQ); + __mmask8 k_gt = _mm512_cmp_pd_mask(a_sq, b_sq, _CMP_GT_OQ); + __mmask8 k_cond = _mm512_kand(k_ge, k_gt); + __m512d w_val = _mm512_mask_blend_pd(k_cond, v_dt_neg, v_c_neg_dt); + + __m512d f_x_safe = _mm512_maskz_mov_pd(active, f_x); + __m512d f_y_safe = _mm512_maskz_mov_pd(active, f_y); + acc_x = _mm512_fmadd_pd(f_x_safe, w_val, acc_x); + acc_y = _mm512_fmadd_pd(f_y_safe, w_val, acc_y); + } + + f_alpha_dt_x += _mm512_reduce_add_pd(acc_x); + f_alpha_dt_y += _mm512_reduce_add_pd(acc_y); + + for (int k = 0; k < board.n_obstacles; k++) { + + double v1_x = pos_x_i - board.obstacles[k].start_x; + double v1_y = pos_y_i - board.obstacles[k].start_y; + + double projection = (v1_x * board.obstacles[k].obstacle_v_x + v1_y * board.obstacles[k].obstacle_v_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + double r_aB_x = pos_x_i - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + double r_aB_y = pos_y_i - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + double r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + double scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + double f_alpha_B_neg_x = r_aB_x * scalar_mult; + double f_alpha_B_neg_y = r_aB_y * scalar_mult; + + double w_val = dt_neg; + double e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y_i : e_y_i); + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + f_alpha_dt_x += f_alpha_B_neg_x * w_val; + f_alpha_dt_y += f_alpha_B_neg_y * w_val; + } + + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p; i++) { + double w_norm_inv = fast_inv_sqrt(w_x[i] * w_x[i] + w_y[i] * w_y[i]); + + double correction_factor = min(1.0, v_max[i] * w_norm_inv); + + curr_vel_x[i] = w_x[i] * correction_factor; + curr_vel_y[i] = w_y[i] * correction_factor; + + pos_x[i] = pos_x[i] + curr_vel_x[i] * dt; + pos_y[i] = pos_y[i] + curr_vel_y[i] * dt; + + if (!color[i] && pos_x[i] > (BOARD_LENGTH - 1.5)) { + pos_x[i] = 1.0; + destination_y[i] = pos_y[i]; + w_x[i] = desired_v0[i]; + w_y[i] = 0.0; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + if (color[i] && pos_x[i] < 1.5) { + pos_x[i] = BOARD_LENGTH - 1.0; + destination_y[i] = pos_y[i]; + w_x[i] = -desired_v0[i]; + w_y[i] = 0.0; + curr_vel_x[i] = w_x[i]; + curr_vel_y[i] = w_y[i]; + } + + pos_y[i] = clamp(pos_y[i], WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + double ex = destination_x[i] - pos_x[i]; + double ey = destination_y[i] - pos_y[i]; + + double e_norm_inv = fast_inv_sqrt(ex * ex + ey * ey); + + e_x[i] = ex * e_norm_inv; + e_y[i] = ey * e_norm_inv; + + double velocity_norm_sq = curr_vel_x[i] * curr_vel_x[i] + curr_vel_y[i] * curr_vel_y[i]; + double sb_sq_i = velocity_norm_sq * delta_t_sq; + double velocity_norm_mul_delta_t = sqrt(sb_sq_i); + + sb_sq[i] = sb_sq_i; + + sb_e_x[i] = e_x[i] * velocity_norm_mul_delta_t; + sb_e_y[i] = e_y[i] * velocity_norm_mul_delta_t; + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix.cpp b/variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix.cpp new file mode 100644 index 0000000..c621275 --- /dev/null +++ b/variants/variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt_sr_expfix.cpp @@ -0,0 +1,576 @@ +// # Changes: Performed Scalar Replacements +// # Predecessor: variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt.cpp + +#include "../headers/board_reduced.hpp" +#include "../headers/constants.hpp" +#include "../headers/pedestrian_reduced.hpp" + +#include + +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0 +#define BOARD_LENGTH 50.0 +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0 +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5 +#define WALL_EPS 1e-3 +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999 + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { + +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 7) & ~7; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + double x = x_gen_left(gen); + double y = y_gen(gen); + + double dest_x = BOARD_LENGTH + 30.0; + double dest_y = y; + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + for (int i = n_p_half; i < n_p; i++) { + double x = x_gen_right(gen); + double y = y_gen(gen); + + double dest_x = -30; + double dest_y = y; + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9; + pos_y[j] = 1e9; + sb_sq[j] = 0.0; + sb_e_x[j] = 0.0; + sb_e_y[j] = 0.0; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 128 MULTs, 112 ADDs +static inline __m512d _avx512_exp_pd(__m512d x) { + + const __m512d log2e = _mm512_set1_pd(1.4426950408889634); + + // # 8 MULTs + __m512d nf = _mm512_roundscale_pd(_mm512_mul_pd(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + const __m512d ln2 = _mm512_set1_pd(0.6931471805599453); + + // # 8 MULTs, 8 ADDs + __m512d r = _mm512_fnmadd_pd(nf, ln2, x); + + const __m512d c13 = _mm512_set1_pd(c13_scalar); + const __m512d c12 = _mm512_set1_pd(c12_scalar); + const __m512d c11 = _mm512_set1_pd(c11_scalar); + const __m512d c10 = _mm512_set1_pd(c10_scalar); + const __m512d c9 = _mm512_set1_pd(c9_scalar); + const __m512d c8 = _mm512_set1_pd(c8_scalar); + const __m512d c7 = _mm512_set1_pd(c7_scalar); + const __m512d c6 = _mm512_set1_pd(c6_scalar); + const __m512d c5 = _mm512_set1_pd(c5_scalar); + const __m512d c4 = _mm512_set1_pd(c4_scalar); + const __m512d c3 = _mm512_set1_pd(c3_scalar); + const __m512d c2 = _mm512_set1_pd(c2_scalar); + const __m512d c1 = _mm512_set1_pd(c1_scalar); + const __m512d c0 = _mm512_set1_pd(c0_scalar); + + __m512d p = c13; + + // # 104 MULTs, 104 ADDs + p = _mm512_fmadd_pd(p, r, c12); + p = _mm512_fmadd_pd(p, r, c11); + p = _mm512_fmadd_pd(p, r, c10); + p = _mm512_fmadd_pd(p, r, c9); + p = _mm512_fmadd_pd(p, r, c8); + p = _mm512_fmadd_pd(p, r, c7); + p = _mm512_fmadd_pd(p, r, c6); + p = _mm512_fmadd_pd(p, r, c5); + p = _mm512_fmadd_pd(p, r, c4); + p = _mm512_fmadd_pd(p, r, c3); + p = _mm512_fmadd_pd(p, r, c2); + p = _mm512_fmadd_pd(p, r, c1); + p = _mm512_fmadd_pd(p, r, c0); + + __m256d nf_lo = _mm512_castpd512_pd256(nf); + __m256d nf_hi = _mm512_extractf64x4_pd(nf, 1); + + __m128i ni32_lo = _mm256_cvtpd_epi32(nf_lo); + __m128i ni32_hi = _mm256_cvtpd_epi32(nf_hi); + + __m256i ni64_lo = _mm256_cvtepi32_epi64(ni32_lo); + __m256i ni64_hi = _mm256_cvtepi32_epi64(ni32_hi); + + __m512i ni64 = _mm512_inserti64x4(_mm512_castsi256_si512(ni64_lo), ni64_hi, 1); + + __m512i biased = _mm512_add_epi64(ni64, _mm512_set1_epi64(1023)); + + __m512i scaled = _mm512_slli_epi64(biased, 52); + + __m512d pow2n = _mm512_castsi512_pd(scaled); + + // # 8 MULTs + return _mm512_mul_pd(p, pow2n); +} + +// # 10 MULTs, 3 ADDs +static inline double fast_inv_sqrt(double number) { + double y = number; + + uint64_t i = bit_cast(y); + + i = 0x5fe6eb50c7b537a9ULL - (i >> 1); + + y = bit_cast(i); + + double x2 = number * 0.5; + y = y * (1.5 - (x2 * y * y)); + y = y * (1.5 - (x2 * y * y)); + y = y * (1.5 - (x2 * y * y)); + + return y; +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 7) & ~7; + + alignas(64) constexpr double lane_offset_arr[8] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; + const __m512d lane_off = _mm512_load_pd(lane_offset_arr); + const __m512d v_neg_v0_div_2s = _mm512_set1_pd(NEG_V0_AB_div_TWO_SIGMA); + const __m512d v_neg_2s_inv = _mm512_set1_pd(NEG_TWO_SIGMA_INV); + const __m512d v_cos_phi_inv = _mm512_set1_pd(cos_phi_inv); + const __m512d v_dt_neg = _mm512_set1_pd(dt_neg); + const __m512d v_c_neg_dt = _mm512_set1_pd(c_neg_times_dt); + const __m512d v_zero = _mm512_setzero_pd(); + + const __m512d v_np = _mm512_set1_pd(n_p); + + // # ADDs: n_iter * n_p * 33 + + // # n_iter * n_p * (n_p_pad / 8) * 232 + + // # n_iter * n_p * board.n_obstacles * 10 + + // # MULTs: n_iter * n_p * 40 + + // # n_iter * n_p * (n_p_pad / 8) * 320 + + // # n_iter * n_p * board.n_obstacles * 13 + + // # DIVs: n_iter * n_p * (n_p_pad / 8) * 8 + + // # n_iter * n_p * board.n_obstacles + + // # SQRTs: n_iter * n_p + + // # n_iter * n_p * (n_p_pad / 8) * 24 + + // # n_iter * n_p * board.n_obstacles + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + + double pos_x_i = pos_x[i]; + double pos_y_i = pos_y[i]; + double e_x_i = e_x[i]; + double e_y_i = e_y[i]; + double desired_v0_i = desired_v0[i]; + double curr_vel_x_i = curr_vel_x[i]; + double curr_vel_y_i = curr_vel_y[i]; + + // # 4 MULTs, 2 ADDs + double f_alpha_dt_x = (e_x_i * desired_v0_i - curr_vel_x_i) * dt_times_tau_alpha_inv; + double f_alpha_dt_y = (e_y_i * desired_v0_i - curr_vel_y_i) * dt_times_tau_alpha_inv; + + const __m512d pix = _mm512_set1_pd(pos_x_i); + const __m512d piy = _mm512_set1_pd(pos_y_i); + const __m512d eix = _mm512_set1_pd(e_x_i); + const __m512d eiy = _mm512_set1_pd(e_y_i); + const __m512d v_i = _mm512_set1_pd((double)i); + + __m512d acc_x = _mm512_setzero_pd(); + __m512d acc_y = _mm512_setzero_pd(); + + for (int j = 0; j < n_p_pad; j += 8) { + + // # 8 ADDs + __m512d j_idx = _mm512_add_pd(_mm512_set1_pd((double)j), lane_off); + + __mmask8 m_neq_i = _mm512_cmp_pd_mask(j_idx, v_i, _CMP_NEQ_OQ); + __mmask8 m_in_range = _mm512_cmp_pd_mask(j_idx, v_np, _CMP_LT_OQ); + __mmask8 active = m_neq_i & m_in_range; + + __m512d pjx = _mm512_loadu_pd(&pos_x[j]); + __m512d pjy = _mm512_loadu_pd(&pos_y[j]); + __m512d sbe_jx = _mm512_loadu_pd(&sb_e_x[j]); + __m512d sbe_jy = _mm512_loadu_pd(&sb_e_y[j]); + __m512d sb_jsq = _mm512_loadu_pd(&sb_sq[j]); + + // # 16 ADDs + __m512d r_ab_x = _mm512_sub_pd(pix, pjx); + __m512d r_ab_y = _mm512_sub_pd(piy, pjy); + + // # 16 MULTs, 8 ADDs + __m512d r_ab_n2 = _mm512_fmadd_pd(r_ab_x, r_ab_x, _mm512_mul_pd(r_ab_y, r_ab_y)); + + // # 8 SQRTs + __m512d r_ab_n = _mm512_sqrt_pd(r_ab_n2); + + // # 16 ADDs + __m512d r_ab2_x = _mm512_sub_pd(r_ab_x, sbe_jx); + __m512d r_ab2_y = _mm512_sub_pd(r_ab_y, sbe_jy); + + // # 16 MULTs, 8 ADDs + __m512d r_ab2_n2 = _mm512_fmadd_pd(r_ab2_x, r_ab2_x, _mm512_mul_pd(r_ab2_y, r_ab2_y)); + + // # 8 SQRTs + __m512d r_ab2_n = _mm512_sqrt_pd(r_ab2_n2); + + // # 8 ADDs + __m512d r_sum = _mm512_add_pd(r_ab_n, r_ab2_n); + + // # 8 MULTs, 8 ADDs + __m512d two_b_sq = _mm512_fmsub_pd(r_sum, r_sum, sb_jsq); + + // # 8 SQRTs + __m512d two_b = _mm512_sqrt_pd(two_b_sq); + + // # 8 MULTs + __m512d e_arg = _mm512_mul_pd(two_b, v_neg_2s_inv); + + // # 128 MULTs, 112 ADDs + __m512d e_val = _avx512_exp_pd(e_arg); + + // # 32 MULTs + __m512d numer = _mm512_mul_pd(_mm512_mul_pd(r_sum, v_neg_v0_div_2s), e_val); + __m512d denom = _mm512_mul_pd(_mm512_mul_pd(two_b, r_ab_n), r_ab2_n); + + __m512d denom_safe = _mm512_mask_blend_pd(active, _mm512_set1_pd(1.0), denom); + + // # 8 DIVs + __m512d smc = _mm512_div_pd(numer, denom_safe); + + // # 16 MULTs + __m512d sm_r_ab = _mm512_mul_pd(smc, r_ab2_n); + __m512d sm_r_ab2 = _mm512_mul_pd(smc, r_ab_n); + + // # 32 MULTs, 16 ADDs + __m512d f_x = _mm512_fmadd_pd(r_ab2_x, sm_r_ab2, _mm512_mul_pd(r_ab_x, sm_r_ab)); + __m512d f_y = _mm512_fmadd_pd(r_ab2_y, sm_r_ab2, _mm512_mul_pd(r_ab_y, sm_r_ab)); + + // # 24 MULTs, 8 ADDs + __m512d a = _mm512_mul_pd(_mm512_fmadd_pd(eix, f_x, _mm512_mul_pd(eiy, f_y)), v_cos_phi_inv); + + // # 8 MULTs + __m512d a_sq = _mm512_mul_pd(a, a); + + // # 16 MULTs, 8 ADDs + __m512d b_sq = _mm512_fmadd_pd(f_x, f_x, _mm512_mul_pd(f_y, f_y)); + + __mmask8 k_ge = _mm512_cmp_pd_mask(a, v_zero, _CMP_GE_OQ); + __mmask8 k_gt = _mm512_cmp_pd_mask(a_sq, b_sq, _CMP_GT_OQ); + __mmask8 k_cond = _mm512_kand(k_ge, k_gt); + __m512d w_val = _mm512_mask_blend_pd(k_cond, v_dt_neg, v_c_neg_dt); + + __m512d f_x_safe = _mm512_maskz_mov_pd(active, f_x); + __m512d f_y_safe = _mm512_maskz_mov_pd(active, f_y); + + // # 16 MULTs, 16 ADDs + acc_x = _mm512_fmadd_pd(f_x_safe, w_val, acc_x); + acc_y = _mm512_fmadd_pd(f_y_safe, w_val, acc_y); + } + + // # 16 ADDs + f_alpha_dt_x += _mm512_reduce_add_pd(acc_x); + f_alpha_dt_y += _mm512_reduce_add_pd(acc_y); + + for (int k = 0; k < board.n_obstacles; k++) { + + double obs_start_x = board.obstacles[k].start_x; + double obs_start_y = board.obstacles[k].start_y; + double obs_v_x = board.obstacles[k].obstacle_v_x; + double obs_v_y = board.obstacles[k].obstacle_v_y; + double obs_length_sq_inv = board.obstacles[k].length_sq_inv; + + // # 2 ADDs + double v1_x = pos_x_i - obs_start_x; + double v1_y = pos_y_i - obs_start_y; + + // # 3 MULTs, 1 ADD + double projection = (v1_x * obs_v_x + v1_y * obs_v_y) * obs_length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + // # 2 MULTs, 4 ADDs + double r_aB_x = pos_x_i - (obs_start_x + obs_v_x * projection); + double r_aB_y = pos_y_i - (obs_start_y + obs_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + + // # 2 MULTs, 1 EXP, 1 DIV + double scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + + // # 2 MULTs + double f_alpha_B_neg_x = r_aB_x * scalar_mult; + double f_alpha_B_neg_y = r_aB_y * scalar_mult; + + double w_val = dt_neg; + double e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y_i : e_y_i); + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTs, 2 ADDs + f_alpha_dt_x += f_alpha_B_neg_x * w_val; + f_alpha_dt_y += f_alpha_B_neg_y * w_val; + } + + // # 2 ADDs + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p; i++) { + + double color_i = color[i]; + double curr_vel_x_i = curr_vel_x[i]; + double curr_vel_y_i = curr_vel_y[i]; + double w_x_i = w_x[i]; + double w_y_i = w_y[i]; + double pos_x_i = pos_x[i]; + double pos_y_i = pos_y[i]; + double e_x_i = e_x[i]; + double e_y_i = e_y[i]; + double v_max_i = v_max[i]; + double desired_v0_i = desired_v0[i]; + double destination_x_i = destination_x[i]; + double destination_y_i = destination_y[i]; + + // # 12 MULTs, 4 ADDs + double w_norm_inv = fast_inv_sqrt(w_x_i * w_x_i + w_y_i * w_y_i); + + // # 1 MULT + double correction_factor = min(1.0, v_max_i * w_norm_inv); + + // # 2 MULTs + curr_vel_x_i = w_x_i * correction_factor; + curr_vel_y_i = w_y_i * correction_factor; + + // # 2 MULTs, 2 ADDs + pos_x_i = pos_x_i + curr_vel_x_i * dt; + pos_y_i = pos_y_i + curr_vel_y_i * dt; + + if (!color_i && pos_x_i > (BOARD_LENGTH_MINUS_ONE_POINT_FIVE)) { + pos_x_i = 1.0; + destination_y_i = pos_y_i; + w_x_i = desired_v0_i; + w_y_i = 0.0; + curr_vel_x_i = w_x_i; + curr_vel_y_i = w_y_i; + } + if (color_i && pos_x_i < 1.5) { + pos_x_i = BOARD_LENGTH_MINUS_ONE; + destination_y_i = pos_y_i; + w_x_i = -desired_v0_i; + w_y_i = 0.0; + curr_vel_x_i = w_x_i; + curr_vel_y_i = w_y_i; + } + + pos_y_i = clamp(pos_y_i, WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + // # 2 ADDs + double ex = destination_x_i - pos_x_i; + double ey = destination_y_i - pos_y_i; + + // # 12 MULTs, 4 ADDs + double e_norm_inv = fast_inv_sqrt(ex * ex + ey * ey); + + // # 2 MULTs + e_x_i = ex * e_norm_inv; + e_y_i = ey * e_norm_inv; + + // # 2 MULTs, 1 ADD + double velocity_norm_sq = curr_vel_x_i * curr_vel_x_i + curr_vel_y_i * curr_vel_y_i; + + // # 1 MULT + double sb_sq_i = velocity_norm_sq * delta_t_sq; + + // # 1 SQRT + double velocity_norm_mul_delta_t = sqrt(sb_sq_i); + + curr_vel_x[i] = curr_vel_x_i; + curr_vel_y[i] = curr_vel_y_i; + + w_x[i] = w_x_i; + w_y[i] = w_y_i; + + pos_x[i] = pos_x_i; + pos_y[i] = pos_y_i; + + e_x[i] = e_x_i; + e_y[i] = e_y_i; + + destination_y[i] = destination_y_i; + + sb_sq[i] = sb_sq_i; + + // # 2 MULTs + sb_e_x[i] = e_x_i * velocity_norm_mul_delta_t; + sb_e_y[i] = e_y_i * velocity_norm_mul_delta_t; + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix.cpp b/variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix.cpp new file mode 100644 index 0000000..7b51d9a --- /dev/null +++ b/variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_expfix.cpp @@ -0,0 +1,563 @@ +// # Changes: Vectorised second pass with AVX-512 +// # Predecessor: variant_inlining_8_SoA_AVX512_polyexp_fastinvsqrt.cpp + +#include "../headers/board_reduced.hpp" +#include "../headers/constants.hpp" +#include "../headers/pedestrian_reduced.hpp" + +#include + +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0 +#define BOARD_LENGTH 50.0 +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0 +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5 +#define WALL_EPS 1e-3 +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999 + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { + +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 7) & ~7; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + double x = x_gen_left(gen); + double y = y_gen(gen); + + double dest_x = BOARD_LENGTH + 30.0; + double dest_y = y; + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + for (int i = n_p_half; i < n_p; i++) { + double x = x_gen_right(gen); + double y = y_gen(gen); + + double dest_x = -30; + double dest_y = y; + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9; + pos_y[j] = 1e9; + sb_sq[j] = 0.0; + sb_e_x[j] = 0.0; + sb_e_y[j] = 0.0; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 128 MULTs, 112 ADDs +static inline __m512d _avx512_exp_pd(__m512d x) { + + const __m512d log2e = _mm512_set1_pd(1.4426950408889634); + + // # 8 MULTs + __m512d nf = _mm512_roundscale_pd(_mm512_mul_pd(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + const __m512d ln2 = _mm512_set1_pd(0.6931471805599453); + + // # 8 MULTs, 8 ADDs + __m512d r = _mm512_fnmadd_pd(nf, ln2, x); + + const __m512d c13 = _mm512_set1_pd(c13_scalar); + const __m512d c12 = _mm512_set1_pd(c12_scalar); + const __m512d c11 = _mm512_set1_pd(c11_scalar); + const __m512d c10 = _mm512_set1_pd(c10_scalar); + const __m512d c9 = _mm512_set1_pd(c9_scalar); + const __m512d c8 = _mm512_set1_pd(c8_scalar); + const __m512d c7 = _mm512_set1_pd(c7_scalar); + const __m512d c6 = _mm512_set1_pd(c6_scalar); + const __m512d c5 = _mm512_set1_pd(c5_scalar); + const __m512d c4 = _mm512_set1_pd(c4_scalar); + const __m512d c3 = _mm512_set1_pd(c3_scalar); + const __m512d c2 = _mm512_set1_pd(c2_scalar); + const __m512d c1 = _mm512_set1_pd(c1_scalar); + const __m512d c0 = _mm512_set1_pd(c0_scalar); + + __m512d p = c13; + + // # 104 MULTs, 104 ADDs + p = _mm512_fmadd_pd(p, r, c12); + p = _mm512_fmadd_pd(p, r, c11); + p = _mm512_fmadd_pd(p, r, c10); + p = _mm512_fmadd_pd(p, r, c9); + p = _mm512_fmadd_pd(p, r, c8); + p = _mm512_fmadd_pd(p, r, c7); + p = _mm512_fmadd_pd(p, r, c6); + p = _mm512_fmadd_pd(p, r, c5); + p = _mm512_fmadd_pd(p, r, c4); + p = _mm512_fmadd_pd(p, r, c3); + p = _mm512_fmadd_pd(p, r, c2); + p = _mm512_fmadd_pd(p, r, c1); + p = _mm512_fmadd_pd(p, r, c0); + + __m256d nf_lo = _mm512_castpd512_pd256(nf); + __m256d nf_hi = _mm512_extractf64x4_pd(nf, 1); + + __m128i ni32_lo = _mm256_cvtpd_epi32(nf_lo); + __m128i ni32_hi = _mm256_cvtpd_epi32(nf_hi); + + __m256i ni64_lo = _mm256_cvtepi32_epi64(ni32_lo); + __m256i ni64_hi = _mm256_cvtepi32_epi64(ni32_hi); + + __m512i ni64 = _mm512_inserti64x4(_mm512_castsi256_si512(ni64_lo), ni64_hi, 1); + + __m512i biased = _mm512_add_epi64(ni64, _mm512_set1_epi64(1023)); + + __m512i scaled = _mm512_slli_epi64(biased, 52); + + __m512d pow2n = _mm512_castsi512_pd(scaled); + + // # 8 MULTs + return _mm512_mul_pd(p, pow2n); +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 7) & ~7; + + alignas(64) constexpr double lane_offset_arr[8] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; + const __m512d lane_off = _mm512_load_pd(lane_offset_arr); + const __m512d v_neg_v0_div_2s = _mm512_set1_pd(NEG_V0_AB_div_TWO_SIGMA); + const __m512d v_neg_2s_inv = _mm512_set1_pd(NEG_TWO_SIGMA_INV); + const __m512d v_cos_phi_inv = _mm512_set1_pd(cos_phi_inv); + const __m512d v_dt_neg = _mm512_set1_pd(dt_neg); + const __m512d v_c_neg_dt = _mm512_set1_pd(c_neg_times_dt); + const __m512d v_zero = _mm512_setzero_pd(); + + const __m512d v_np = _mm512_set1_pd(n_p); + + // # ADDs: n_iter * n_p * 20 + + // # n_iter * n_p * (n_p_pad / 8) * 232 + + // # n_iter * n_p * board.n_obstacles * 10 + + // # n_iter * (n_p_pad / 8) * 56 + + // # MULTs: n_iter * n_p * 4 + + // # n_iter * n_p * (n_p_pad / 8) * 320 + + // # n_iter * n_p * board.n_obstacles * 13 + + // # n_iter * (n_p_pad / 8) * 120 + + // # DIVs: n_iter * n_p * (n_p_pad / 8) * 8 + + // # n_iter * n_p * board.n_obstacles + + // # n_iter * (n_p_pad / 8) * 16 + + // # SQRTs: n_iter * n_p * (n_p_pad / 8) * 24 + + // # n_iter * n_p * board.n_obstacles + + // # n_iter * (n_p_pad / 8) * 24 + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + + for (int i = 0; i < n_p; i++) { + double pos_x_i = pos_x[i]; + double pos_y_i = pos_y[i]; + double e_x_i = e_x[i]; + double e_y_i = e_y[i]; + double desired_v0_i = desired_v0[i]; + double curr_vel_x_i = curr_vel_x[i]; + double curr_vel_y_i = curr_vel_y[i]; + + // # 4 MULTs, 2 ADDs + double f_alpha_dt_x = (e_x_i * desired_v0_i - curr_vel_x_i) * dt_times_tau_alpha_inv; + double f_alpha_dt_y = (e_y_i * desired_v0_i - curr_vel_y_i) * dt_times_tau_alpha_inv; + + const __m512d pix = _mm512_set1_pd(pos_x_i); + const __m512d piy = _mm512_set1_pd(pos_y_i); + const __m512d eix = _mm512_set1_pd(e_x_i); + const __m512d eiy = _mm512_set1_pd(e_y_i); + const __m512d v_i = _mm512_set1_pd((double)i); + + __m512d acc_x = _mm512_setzero_pd(); + __m512d acc_y = _mm512_setzero_pd(); + + for (int j = 0; j < n_p_pad; j += 8) { + + // # 8 ADDs + __m512d j_idx = _mm512_add_pd(_mm512_set1_pd((double)j), lane_off); + + __mmask8 m_neq_i = _mm512_cmp_pd_mask(j_idx, v_i, _CMP_NEQ_OQ); + __mmask8 m_in_range = _mm512_cmp_pd_mask(j_idx, v_np, _CMP_LT_OQ); + __mmask8 active = m_neq_i & m_in_range; + + __m512d pjx = _mm512_loadu_pd(&pos_x[j]); + __m512d pjy = _mm512_loadu_pd(&pos_y[j]); + __m512d sbe_jx = _mm512_loadu_pd(&sb_e_x[j]); + __m512d sbe_jy = _mm512_loadu_pd(&sb_e_y[j]); + __m512d sb_jsq = _mm512_loadu_pd(&sb_sq[j]); + + // # 16 ADDs + __m512d r_ab_x = _mm512_sub_pd(pix, pjx); + __m512d r_ab_y = _mm512_sub_pd(piy, pjy); + + // # 16 MULTs, 8 ADDs + __m512d r_ab_n2 = _mm512_fmadd_pd(r_ab_x, r_ab_x, _mm512_mul_pd(r_ab_y, r_ab_y)); + + // # 8 SQRTs + __m512d r_ab_n = _mm512_sqrt_pd(r_ab_n2); + + // # 16 ADDs + __m512d r_ab2_x = _mm512_sub_pd(r_ab_x, sbe_jx); + __m512d r_ab2_y = _mm512_sub_pd(r_ab_y, sbe_jy); + + // # 16 MULTs, 8 ADDs + __m512d r_ab2_n2 = _mm512_fmadd_pd(r_ab2_x, r_ab2_x, _mm512_mul_pd(r_ab2_y, r_ab2_y)); + + // # 8 SQRTs + __m512d r_ab2_n = _mm512_sqrt_pd(r_ab2_n2); + + // # 8 ADDs + __m512d r_sum = _mm512_add_pd(r_ab_n, r_ab2_n); + + // # 8 MULTs, 8 ADDs + __m512d two_b_sq = _mm512_fmsub_pd(r_sum, r_sum, sb_jsq); + + // # 8 SQRTs + __m512d two_b = _mm512_sqrt_pd(two_b_sq); + + // # 8 MULTs + __m512d e_arg = _mm512_mul_pd(two_b, v_neg_2s_inv); + + // # 128 MULTs, 112 ADDs + __m512d e_val = _avx512_exp_pd(e_arg); + + // # 32 MULTs + __m512d numer = _mm512_mul_pd(_mm512_mul_pd(r_sum, v_neg_v0_div_2s), e_val); + __m512d denom = _mm512_mul_pd(_mm512_mul_pd(two_b, r_ab_n), r_ab2_n); + + // # 8 DIVs + __m512d smc = _mm512_div_pd(numer, denom); + + // # 16 MULTs + __m512d sm_r_ab = _mm512_mul_pd(smc, r_ab2_n); + __m512d sm_r_ab2 = _mm512_mul_pd(smc, r_ab_n); + + // # 32 MULTs, 16 ADDs + __m512d f_x = _mm512_fmadd_pd(r_ab2_x, sm_r_ab2, _mm512_mul_pd(r_ab_x, sm_r_ab)); + __m512d f_y = _mm512_fmadd_pd(r_ab2_y, sm_r_ab2, _mm512_mul_pd(r_ab_y, sm_r_ab)); + + // # 24 MULTs, 8 ADDs + __m512d a = _mm512_mul_pd(_mm512_fmadd_pd(eix, f_x, _mm512_mul_pd(eiy, f_y)), v_cos_phi_inv); + + // # 8 MULTs + __m512d a_sq = _mm512_mul_pd(a, a); + + // # 16 MULTs, 8 ADDs + __m512d b_sq = _mm512_fmadd_pd(f_x, f_x, _mm512_mul_pd(f_y, f_y)); + + __mmask8 k_ge = _mm512_cmp_pd_mask(a, v_zero, _CMP_GE_OQ); + __mmask8 k_gt = _mm512_cmp_pd_mask(a_sq, b_sq, _CMP_GT_OQ); + __mmask8 k_cond = _mm512_kand(k_ge, k_gt); + __m512d w_val = _mm512_mask_blend_pd(k_cond, v_dt_neg, v_c_neg_dt); + + __m512d f_x_safe = _mm512_maskz_mov_pd(active, f_x); + __m512d f_y_safe = _mm512_maskz_mov_pd(active, f_y); + + // # 16 MULTs, 16 ADDs + acc_x = _mm512_fmadd_pd(f_x_safe, w_val, acc_x); + acc_y = _mm512_fmadd_pd(f_y_safe, w_val, acc_y); + } + + // # 16 ADDS + f_alpha_dt_x += _mm512_reduce_add_pd(acc_x); + f_alpha_dt_y += _mm512_reduce_add_pd(acc_y); + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + double v1_x = pos_x_i - board.obstacles[k].start_x; + double v1_y = pos_y_i - board.obstacles[k].start_y; + + // # 3 MULTs, 1 ADD + double projection = (v1_x * board.obstacles[k].obstacle_v_x + v1_y * board.obstacles[k].obstacle_v_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + // # 4 ADDs, 2 MULTs + double r_aB_x = pos_x_i - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + double r_aB_y = pos_y_i - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + + // # 2 MULTs, 1 EXP, 1 DIV + double scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + + // # 2 MULTs + double f_alpha_B_neg_x = r_aB_x * scalar_mult; + double f_alpha_B_neg_y = r_aB_y * scalar_mult; + + double w_val = dt_neg; + double e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y_i : e_y_i); + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTs, 2 ADDs + f_alpha_dt_x += f_alpha_B_neg_x * w_val; + f_alpha_dt_y += f_alpha_B_neg_y * w_val; + } + + // # 2 ADDs + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p_pad; i += 8) { + + __m512d w_x_i_vec = _mm512_loadu_pd(&w_x[i]); + __m512d w_y_i_vec = _mm512_loadu_pd(&w_y[i]); + __m512d v_max_i_vec = _mm512_loadu_pd(&v_max[i]); + __m512d pos_x_i_vec = _mm512_loadu_pd(&pos_x[i]); + __m512d pos_y_i_vec = _mm512_loadu_pd(&pos_y[i]); + __m512d destination_y_i_vec = _mm512_loadu_pd(&destination_y[i]); + __m512d destination_x_i_vec = _mm512_loadu_pd(&destination_x[i]); + __m512d desired_v0_i_vec = _mm512_loadu_pd(&desired_v0[i]); + + __m256i color_i_vec = _mm256_loadu_si256((__m256i *)&color[i]); + + // # 16 MULTs, 8 ADDs + __m512d w_norm_sq = _mm512_fmadd_pd(w_x_i_vec, w_x_i_vec, _mm512_mul_pd(w_y_i_vec, w_y_i_vec)); + + // # 8 SQRTs + __m512d w_norm = _mm512_sqrt_pd(w_norm_sq); + + // # 8 DIVs + __m512d correction_factor = _mm512_min_pd(_mm512_set1_pd(1.0), _mm512_div_pd(v_max_i_vec, w_norm)); + + // # 16 MULTs + __m512d curr_vel_x_i_vec = _mm512_mul_pd(w_x_i_vec, correction_factor); + __m512d curr_vel_y_i_vec = _mm512_mul_pd(w_y_i_vec, correction_factor); + + __m512d dt_vec = _mm512_set1_pd(dt); + + // # 16 MULTs, 16 ADDs + pos_x_i_vec = _mm512_fmadd_pd(curr_vel_x_i_vec, dt_vec, pos_x_i_vec); + pos_y_i_vec = _mm512_fmadd_pd(curr_vel_y_i_vec, dt_vec, pos_y_i_vec); + + __mmask8 cond_1_left = _mm256_cmpeq_epi32_mask(color_i_vec, _mm256_setzero_si256()); + __mmask8 cond_1_right = _mm512_cmp_pd_mask(pos_x_i_vec, _mm512_set1_pd(BOARD_LENGTH_MINUS_ONE_POINT_FIVE), _CMP_GT_OQ); + __mmask8 cond_1 = cond_1_left & cond_1_right; + + pos_x_i_vec = _mm512_mask_blend_pd(cond_1, pos_x_i_vec, _mm512_set1_pd(1.0)); + destination_y_i_vec = _mm512_mask_blend_pd(cond_1, destination_y_i_vec, pos_y_i_vec); + w_x_i_vec = _mm512_mask_blend_pd(cond_1, w_x_i_vec, desired_v0_i_vec); + w_y_i_vec = _mm512_mask_blend_pd(cond_1, w_y_i_vec, _mm512_setzero_pd()); + curr_vel_x_i_vec = _mm512_mask_blend_pd(cond_1, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_pd(cond_1, curr_vel_y_i_vec, w_y_i_vec); + + __mmask8 cond_2_left = _mm256_cmpeq_epi32_mask(color_i_vec, _mm256_set1_epi32(1)); + __mmask8 cond_2_right = _mm512_cmp_pd_mask(pos_x_i_vec, _mm512_set1_pd(1.5), _CMP_LT_OQ); + __mmask8 cond_2 = cond_2_left & cond_2_right; + + pos_x_i_vec = _mm512_mask_blend_pd(cond_2, pos_x_i_vec, _mm512_set1_pd(BOARD_LENGTH - 1.0)); + destination_y_i_vec = _mm512_mask_blend_pd(cond_2, destination_y_i_vec, pos_y_i_vec); + __m512d neg_desired_v0 = _mm512_xor_pd(desired_v0_i_vec, _mm512_set1_pd(-0.0)); + w_x_i_vec = _mm512_mask_blend_pd(cond_2, w_x_i_vec, neg_desired_v0); + w_y_i_vec = _mm512_mask_blend_pd(cond_2, w_y_i_vec, _mm512_setzero_pd()); + curr_vel_x_i_vec = _mm512_mask_blend_pd(cond_2, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_pd(cond_2, curr_vel_y_i_vec, w_y_i_vec); + + pos_y_i_vec = _mm512_max_pd(pos_y_i_vec, _mm512_set1_pd(WALL_EPS)); + pos_y_i_vec = _mm512_min_pd(pos_y_i_vec, _mm512_set1_pd(BOARD_WIDTH_MINUS_WALL_EPS)); + + // # 16 ADDs + __m512d ex_vec = _mm512_sub_pd(destination_x_i_vec, pos_x_i_vec); + __m512d ey_vec = _mm512_sub_pd(destination_y_i_vec, pos_y_i_vec); + + // # 16 MULTs, 8 ADDs + __m512d e_norm_sq = _mm512_fmadd_pd(ex_vec, ex_vec, _mm512_mul_pd(ey_vec, ey_vec)); + + // # 8 SQRTs + __m512d e_norm = _mm512_sqrt_pd(e_norm_sq); + + // # 8 DIVs + __m512d e_norm_inv = _mm512_div_pd(_mm512_set1_pd(1.0), e_norm); + + // # 16 MULT + __m512d e_x_i_vec = _mm512_mul_pd(ex_vec, e_norm_inv); + __m512d e_y_i_vec = _mm512_mul_pd(ey_vec, e_norm_inv); + + // # 16 MULTs, 8 ADDs + __m512d vel_norm_sq = _mm512_fmadd_pd(curr_vel_x_i_vec, curr_vel_x_i_vec, _mm512_mul_pd(curr_vel_y_i_vec, curr_vel_y_i_vec)); + + // # 8 MULTs + __m512d sb_sq_i_vec = _mm512_mul_pd(vel_norm_sq, _mm512_set1_pd(delta_t_sq)); + + // # 8 SQRTs + __m512d vel_norm_dt = _mm512_sqrt_pd(sb_sq_i_vec); + + _mm512_storeu_pd(&curr_vel_x[i], curr_vel_x_i_vec); + _mm512_storeu_pd(&curr_vel_y[i], curr_vel_y_i_vec); + _mm512_storeu_pd(&w_x[i], w_x_i_vec); + _mm512_storeu_pd(&w_y[i], w_y_i_vec); + _mm512_storeu_pd(&pos_x[i], pos_x_i_vec); + _mm512_storeu_pd(&pos_y[i], pos_y_i_vec); + _mm512_storeu_pd(&e_x[i], e_x_i_vec); + _mm512_storeu_pd(&e_y[i], e_y_i_vec); + _mm512_storeu_pd(&destination_y[i], destination_y_i_vec); + _mm512_storeu_pd(&sb_sq[i], sb_sq_i_vec); + + // # 16 MULTs + _mm512_storeu_pd(&sb_e_x[i], _mm512_mul_pd(e_x_i_vec, vel_norm_dt)); + _mm512_storeu_pd(&sb_e_y[i], _mm512_mul_pd(e_y_i_vec, vel_norm_dt)); + } +#if !BENCHMARK + for (int i = 0; i < n_p; i++) { + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp b/variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp new file mode 100644 index 0000000..486512c --- /dev/null +++ b/variants/variant_inlining_8_SoA_AVX512_polyexp_moreavx_ilp_2_expfix.cpp @@ -0,0 +1,640 @@ +// # Changes: Added ILP with k = 2 to j-loop +// # Predecessor: variant_inlining_8_SoA_AVX512_polyexp_moreavx.cpp + +#include "../headers/board_reduced.hpp" +#include "../headers/constants.hpp" +#include "../headers/pedestrian_reduced.hpp" + +#include + +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0 +#define BOARD_LENGTH 50.0 +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0 +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5 +#define WALL_EPS 1e-3 +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999 + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +alignas(64) vector pos_x, pos_y; +alignas(64) vector sb_sq; +alignas(64) vector sb_e_x, sb_e_y; +alignas(64) vector e_x, e_y; +alignas(64) vector curr_vel_x, curr_vel_y; +alignas(64) vector w_x, w_y; +alignas(64) vector desired_v0; +alignas(64) vector v_max; +alignas(64) vector destination_x, destination_y; +alignas(64) vector color; + +Pedestrian *init_pedestrians(int n_p) { + +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + const int n_p_pad = (n_p + 15) & ~15; + + pos_x.resize(n_p_pad); + pos_y.resize(n_p_pad); + sb_sq.resize(n_p_pad); + sb_e_x.resize(n_p_pad); + sb_e_y.resize(n_p_pad); + e_x.resize(n_p_pad); + e_y.resize(n_p_pad); + curr_vel_x.resize(n_p_pad); + curr_vel_y.resize(n_p_pad); + w_x.resize(n_p_pad); + w_y.resize(n_p_pad); + desired_v0.resize(n_p_pad); + v_max.resize(n_p_pad); + destination_x.resize(n_p_pad); + destination_y.resize(n_p_pad); + color.resize(n_p_pad); + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + double x = x_gen_left(gen); + double y = y_gen(gen); + + double dest_x = BOARD_LENGTH + 30.0; + double dest_y = y; + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 0; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + for (int i = n_p_half; i < n_p; i++) { + double x = x_gen_right(gen); + double y = y_gen(gen); + + double dest_x = -30; + double dest_y = y; + + double init_e_x = dest_x - x; + double init_e_y = dest_y - y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double d_v0; + do { + d_v0 = velocity_gen(gen); + } while (d_v0 <= 0.1); + + double v_m = 1.3 * d_v0; + + color[i] = 1; + pos_x[i] = x; + pos_y[i] = y; + e_x[i] = init_e_unit_x; + e_y[i] = init_e_unit_y; + v_max[i] = v_m; + desired_v0[i] = d_v0; + destination_x[i] = dest_x; + destination_y[i] = dest_y; + + w_x[i] = 0.0; + w_y[i] = 0.0; + curr_vel_x[i] = 0.0; + curr_vel_y[i] = 0.0; + sb_sq[i] = 0.0; + sb_e_x[i] = 0.0; + sb_e_y[i] = 0.0; + } + + for (int j = n_p; j < n_p_pad; j++) { + pos_x[j] = 1e9; + pos_y[j] = 1e9; + sb_sq[j] = 0.0; + sb_e_x[j] = 0.0; + sb_e_y[j] = 0.0; + } + return nullptr; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +// # 128 MULTs, 112 ADDs +static inline __m512d _avx512_exp_pd(__m512d x) { + + const __m512d log2e = _mm512_set1_pd(1.4426950408889634); + + // # 8 MULTs + __m512d nf = _mm512_roundscale_pd(_mm512_mul_pd(x, log2e), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + const __m512d ln2 = _mm512_set1_pd(0.6931471805599453); + + // # 8 MULTs, 8 ADDs + __m512d r = _mm512_fnmadd_pd(nf, ln2, x); + + const __m512d c13 = _mm512_set1_pd(c13_scalar); + const __m512d c12 = _mm512_set1_pd(c12_scalar); + const __m512d c11 = _mm512_set1_pd(c11_scalar); + const __m512d c10 = _mm512_set1_pd(c10_scalar); + const __m512d c9 = _mm512_set1_pd(c9_scalar); + const __m512d c8 = _mm512_set1_pd(c8_scalar); + const __m512d c7 = _mm512_set1_pd(c7_scalar); + const __m512d c6 = _mm512_set1_pd(c6_scalar); + const __m512d c5 = _mm512_set1_pd(c5_scalar); + const __m512d c4 = _mm512_set1_pd(c4_scalar); + const __m512d c3 = _mm512_set1_pd(c3_scalar); + const __m512d c2 = _mm512_set1_pd(c2_scalar); + const __m512d c1 = _mm512_set1_pd(c1_scalar); + const __m512d c0 = _mm512_set1_pd(c0_scalar); + + __m512d p = c13; + + // # 104 MULTs, 104 ADDs + p = _mm512_fmadd_pd(p, r, c12); + p = _mm512_fmadd_pd(p, r, c11); + p = _mm512_fmadd_pd(p, r, c10); + p = _mm512_fmadd_pd(p, r, c9); + p = _mm512_fmadd_pd(p, r, c8); + p = _mm512_fmadd_pd(p, r, c7); + p = _mm512_fmadd_pd(p, r, c6); + p = _mm512_fmadd_pd(p, r, c5); + p = _mm512_fmadd_pd(p, r, c4); + p = _mm512_fmadd_pd(p, r, c3); + p = _mm512_fmadd_pd(p, r, c2); + p = _mm512_fmadd_pd(p, r, c1); + p = _mm512_fmadd_pd(p, r, c0); + + __m256d nf_lo = _mm512_castpd512_pd256(nf); + __m256d nf_hi = _mm512_extractf64x4_pd(nf, 1); + + __m128i ni32_lo = _mm256_cvtpd_epi32(nf_lo); + __m128i ni32_hi = _mm256_cvtpd_epi32(nf_hi); + + __m256i ni64_lo = _mm256_cvtepi32_epi64(ni32_lo); + __m256i ni64_hi = _mm256_cvtepi32_epi64(ni32_hi); + + __m512i ni64 = _mm512_inserti64x4(_mm512_castsi256_si512(ni64_lo), ni64_hi, 1); + + __m512i biased = _mm512_add_epi64(ni64, _mm512_set1_epi64(1023)); + + __m512i scaled = _mm512_slli_epi64(biased, 52); + + __m512d pow2n = _mm512_castsi512_pd(scaled); + + // # 8 MULTs + return _mm512_mul_pd(p, pow2n); +} + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + samples.emplace_back(0, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + + const int n_p_pad = (n_p + 15) & ~15; + + alignas(64) constexpr double lane_offset_arr[8] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0}; + const __m512d lane_off = _mm512_load_pd(lane_offset_arr); + + const __m512d v_neg_v0_div_2s = _mm512_set1_pd(NEG_V0_AB_div_TWO_SIGMA); + const __m512d v_neg_2s_inv = _mm512_set1_pd(NEG_TWO_SIGMA_INV); + const __m512d v_cos_phi_sq = _mm512_set1_pd(cos_phi_sq); + const __m512d v_dt_neg = _mm512_set1_pd(dt_neg); + const __m512d v_c_neg_dt = _mm512_set1_pd(c_neg_times_dt); + const __m512d v_zero = _mm512_setzero_pd(); + const __m512d v_one = _mm512_set1_pd(1.0f); + const __m512d v_np = _mm512_set1_pd((float)n_p); + const __m512d v_exp_min = _mm512_set1_pd(-87.0f); + + // # ADDs: n_iter * n_p * 36 + + // # n_iter * n_p * (n_p_pad / 16) * 464 + + // # n_iter * n_p * board.n_obstacles * 10 + + // # n_iter * (n_p_pad / 8) * 56 + + // # MULTs: n_iter * n_p * 4 + + // # n_iter * n_p * (n_p_pad / 16) * 640 + + // # n_iter * n_p * board.n_obstacles * 13 + + // # n_iter * (n_p_pad / 8) * 120 + + // # DIVs: n_iter * n_p * (n_p_pad / 16) * 16 + + // # n_iter * n_p * board.n_obstacles + + // # n_iter * (n_p_pad / 8) * 16 + + // # SQRTs: n_iter * n_p * (n_p_pad / 16) * 48 + + // # n_iter * n_p * board.n_obstacles + + // # n_iter * (n_p_pad / 8) * 24 + + // # EXPs: n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + + for (int i = 0; i < n_p; i++) { + + double pos_x_i = pos_x[i]; + double pos_y_i = pos_y[i]; + double e_x_i = e_x[i]; + double e_y_i = e_y[i]; + double desired_v0_i = desired_v0[i]; + double curr_vel_x_i = curr_vel_x[i]; + double curr_vel_y_i = curr_vel_y[i]; + + // # 4 MULTs, 2 ADDs + double f_alpha_dt_x = (e_x_i * desired_v0_i - curr_vel_x_i) * dt_times_tau_alpha_inv; + double f_alpha_dt_y = (e_y_i * desired_v0_i - curr_vel_y_i) * dt_times_tau_alpha_inv; + + const __m512d pix = _mm512_set1_pd(pos_x_i); + const __m512d piy = _mm512_set1_pd(pos_y_i); + const __m512d eix = _mm512_set1_pd(e_x_i); + const __m512d eiy = _mm512_set1_pd(e_y_i); + const __m512d v_i = _mm512_set1_pd((double)i); + + __m512d acc_x_0 = _mm512_setzero_pd(); + __m512d acc_y_0 = _mm512_setzero_pd(); + __m512d acc_x_1 = _mm512_setzero_pd(); + __m512d acc_y_1 = _mm512_setzero_pd(); + + for (int j = 0; j < n_p_pad; j += 16) { + + // # 16 ADDs + __m512d j_idx_0 = _mm512_add_pd(_mm512_set1_pd((double)j), lane_off); + __m512d j_idx_1 = _mm512_add_pd(_mm512_set1_pd((double)j + 8), lane_off); + + __mmask8 m_neq_i_0 = _mm512_cmp_pd_mask(j_idx_0, v_i, _CMP_NEQ_OQ); + __mmask8 m_neq_i_1 = _mm512_cmp_pd_mask(j_idx_1, v_i, _CMP_NEQ_OQ); + + __mmask8 m_in_range_0 = _mm512_cmp_pd_mask(j_idx_0, v_np, _CMP_LT_OQ); + __mmask8 m_in_range_1 = _mm512_cmp_pd_mask(j_idx_1, v_np, _CMP_LT_OQ); + + __mmask8 active_0 = m_neq_i_0 & m_in_range_0; + __mmask8 active_1 = m_neq_i_1 & m_in_range_1; + + __m512d pjx_0 = _mm512_loadu_pd(&pos_x[j]); + __m512d pjx_1 = _mm512_loadu_pd(&pos_x[j + 8]); + + __m512d pjy_0 = _mm512_loadu_pd(&pos_y[j]); + __m512d pjy_1 = _mm512_loadu_pd(&pos_y[j + 8]); + + __m512d sbe_jx_0 = _mm512_loadu_pd(&sb_e_x[j]); + __m512d sbe_jx_1 = _mm512_loadu_pd(&sb_e_x[j + 8]); + + __m512d sbe_jy_0 = _mm512_loadu_pd(&sb_e_y[j]); + __m512d sbe_jy_1 = _mm512_loadu_pd(&sb_e_y[j + 8]); + + __m512d sb_jsq_0 = _mm512_loadu_pd(&sb_sq[j]); + __m512d sb_jsq_1 = _mm512_loadu_pd(&sb_sq[j + 8]); + + // # 16 ADDs + __m512d r_ab_x_0 = _mm512_sub_pd(pix, pjx_0); + __m512d r_ab_x_1 = _mm512_sub_pd(pix, pjx_1); + + // # 16 ADDs + __m512d r_ab_y_0 = _mm512_sub_pd(piy, pjy_0); + __m512d r_ab_y_1 = _mm512_sub_pd(piy, pjy_1); + + // # 32 MULTs, 16 ADDs + __m512d r_ab_n2_0 = _mm512_fmadd_pd(r_ab_x_0, r_ab_x_0, _mm512_mul_pd(r_ab_y_0, r_ab_y_0)); + __m512d r_ab_n2_1 = _mm512_fmadd_pd(r_ab_x_1, r_ab_x_1, _mm512_mul_pd(r_ab_y_1, r_ab_y_1)); + + // # 16 SQRTs + __m512d r_ab_n_0 = _mm512_sqrt_pd(r_ab_n2_0); + __m512d r_ab_n_1 = _mm512_sqrt_pd(r_ab_n2_1); + + // # 16 ADDs + __m512d r_ab2_x_0 = _mm512_sub_pd(r_ab_x_0, sbe_jx_0); + __m512d r_ab2_x_1 = _mm512_sub_pd(r_ab_x_1, sbe_jx_1); + + // # 16 ADDs + __m512d r_ab2_y_0 = _mm512_sub_pd(r_ab_y_0, sbe_jy_0); + __m512d r_ab2_y_1 = _mm512_sub_pd(r_ab_y_1, sbe_jy_1); + + // # 32 MULTs, 16 ADDs + __m512d r_ab2_n2_0 = _mm512_fmadd_pd(r_ab2_x_0, r_ab2_x_0, _mm512_mul_pd(r_ab2_y_0, r_ab2_y_0)); + __m512d r_ab2_n2_1 = _mm512_fmadd_pd(r_ab2_x_1, r_ab2_x_1, _mm512_mul_pd(r_ab2_y_1, r_ab2_y_1)); + + // # 16 SQRTs + __m512d r_ab2_n_0 = _mm512_sqrt_pd(r_ab2_n2_0); + __m512d r_ab2_n_1 = _mm512_sqrt_pd(r_ab2_n2_1); + + // # 16 ADDs + __m512d r_sum_0 = _mm512_add_pd(r_ab_n_0, r_ab2_n_0); + __m512d r_sum_1 = _mm512_add_pd(r_ab_n_1, r_ab2_n_1); + + // # 16 MULTs, 16 ADDs + __m512d two_b_sq_0 = _mm512_fmsub_pd(r_sum_0, r_sum_0, sb_jsq_0); + __m512d two_b_sq_1 = _mm512_fmsub_pd(r_sum_1, r_sum_1, sb_jsq_1); + + // # 16 SQRTs + __m512d two_b_0 = _mm512_sqrt_pd(two_b_sq_0); + __m512d two_b_1 = _mm512_sqrt_pd(two_b_sq_1); + + // # 16 MULTs + __m512d e_arg_0 = _mm512_mul_pd(two_b_0, v_neg_2s_inv); + __m512d e_arg_1 = _mm512_mul_pd(two_b_1, v_neg_2s_inv); + + e_arg_0 = _mm512_max_pd(e_arg_0, v_exp_min); + e_arg_1 = _mm512_max_pd(e_arg_1, v_exp_min); + + // # 256 MULTs, 224 ADDs + __m512d e_val_0 = _avx512_exp_pd(e_arg_0); + __m512d e_val_1 = _avx512_exp_pd(e_arg_1); + + // # 32 MULTs + __m512d numer_0 = _mm512_mul_pd(_mm512_mul_pd(r_sum_0, v_neg_v0_div_2s), e_val_0); + __m512d numer_1 = _mm512_mul_pd(_mm512_mul_pd(r_sum_1, v_neg_v0_div_2s), e_val_1); + + // # 32 MULTs + __m512d denom_0 = _mm512_mul_pd(_mm512_mul_pd(two_b_0, r_ab_n_0), r_ab2_n_0); + __m512d denom_1 = _mm512_mul_pd(_mm512_mul_pd(two_b_1, r_ab_n_1), r_ab2_n_1); + + __m512d denom_safe_0 = _mm512_mask_blend_pd(active_0, v_one, denom_0); + __m512d denom_safe_1 = _mm512_mask_blend_pd(active_1, v_one, denom_1); + + // # 16 DIVs + __m512d smc_0 = _mm512_div_pd(numer_0, denom_safe_0); + __m512d smc_1 = _mm512_div_pd(numer_1, denom_safe_1); + + // # 16 MULTs + __m512d sm_r_ab_0 = _mm512_mul_pd(smc_0, r_ab2_n_0); + __m512d sm_r_ab_1 = _mm512_mul_pd(smc_1, r_ab2_n_1); + + // # 16 MULTs + __m512d sm_r_ab2_0 = _mm512_mul_pd(smc_0, r_ab_n_0); + __m512d sm_r_ab2_1 = _mm512_mul_pd(smc_1, r_ab_n_1); + + // # 32 MULTs, 16 ADDs + __m512d f_x_0 = _mm512_fmadd_pd(r_ab2_x_0, sm_r_ab2_0, _mm512_mul_pd(r_ab_x_0, sm_r_ab_0)); + __m512d f_x_1 = _mm512_fmadd_pd(r_ab2_x_1, sm_r_ab2_1, _mm512_mul_pd(r_ab_x_1, sm_r_ab_1)); + + // # 32 MULTs, 16 ADDs + __m512d f_y_0 = _mm512_fmadd_pd(r_ab2_y_0, sm_r_ab2_0, _mm512_mul_pd(r_ab_y_0, sm_r_ab_0)); + __m512d f_y_1 = _mm512_fmadd_pd(r_ab2_y_1, sm_r_ab2_1, _mm512_mul_pd(r_ab_y_1, sm_r_ab_1)); + + // # 32 MULTs, 16 ADDs + __m512d f_norm_sq_0 = _mm512_fmadd_pd(f_x_0, f_x_0, _mm512_mul_pd(f_y_0, f_y_0)); + __m512d f_norm_sq_1 = _mm512_fmadd_pd(f_x_1, f_x_1, _mm512_mul_pd(f_y_1, f_y_1)); + + // # 16 MULTs + __m512d rhs_0 = _mm512_mul_pd(f_norm_sq_0, v_cos_phi_sq); + __m512d rhs_1 = _mm512_mul_pd(f_norm_sq_1, v_cos_phi_sq); + + // # 32 MULTs, 16 ADDs + __m512d e_dot_f_0 = _mm512_fmadd_pd(eix, f_x_0, _mm512_mul_pd(eiy, f_y_0)); + __m512d e_dot_f_1 = _mm512_fmadd_pd(eix, f_x_1, _mm512_mul_pd(eiy, f_y_1)); + + // # 16 MULTs + __m512d e_dot_f_sq_0 = _mm512_mul_pd(e_dot_f_0, e_dot_f_0); + __m512d e_dot_f_sq_1 = _mm512_mul_pd(e_dot_f_1, e_dot_f_1); + + __mmask8 c1_0 = _mm512_cmp_pd_mask(e_dot_f_0, v_zero, _CMP_LT_OQ); + __mmask8 c1_1 = _mm512_cmp_pd_mask(e_dot_f_1, v_zero, _CMP_LT_OQ); + + __mmask8 c2_0 = _mm512_cmp_pd_mask(e_dot_f_sq_0, rhs_0, _CMP_GT_OQ); + __mmask8 c2_1 = _mm512_cmp_pd_mask(e_dot_f_sq_1, rhs_1, _CMP_GT_OQ); + + __mmask8 cond_0 = c1_0 & c2_0; + __mmask8 cond_1 = c1_1 & c2_1; + + __m512d w_val_0 = _mm512_mask_blend_pd(cond_0, v_dt_neg, v_c_neg_dt); + __m512d w_val_1 = _mm512_mask_blend_pd(cond_1, v_dt_neg, v_c_neg_dt); + + __m512d f_x_safe_0 = _mm512_maskz_mov_pd(active_0, f_x_0); + __m512d f_x_safe_1 = _mm512_maskz_mov_pd(active_1, f_x_1); + + __m512d f_y_safe_0 = _mm512_maskz_mov_pd(active_0, f_y_0); + __m512d f_y_safe_1 = _mm512_maskz_mov_pd(active_1, f_y_1); + + // # 16 MULTs, 16 ADDs + acc_x_0 = _mm512_fmadd_pd(f_x_safe_0, w_val_0, acc_x_0); + acc_x_1 = _mm512_fmadd_pd(f_x_safe_1, w_val_1, acc_x_1); + + // # 16 MULTs, 16 ADDs + acc_y_0 = _mm512_fmadd_pd(f_y_safe_0, w_val_0, acc_y_0); + acc_y_1 = _mm512_fmadd_pd(f_y_safe_1, w_val_1, acc_y_1); + } + + // # 32 ADDs + f_alpha_dt_x += _mm512_reduce_add_pd(_mm512_add_pd(acc_x_0, acc_x_1)); + f_alpha_dt_y += _mm512_reduce_add_pd(_mm512_add_pd(acc_y_0, acc_y_1)); + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + double v1_x = pos_x_i - board.obstacles[k].start_x; + double v1_y = pos_y_i - board.obstacles[k].start_y; + + // # 3 MULTs, 1 ADD + double projection = (v1_x * board.obstacles[k].obstacle_v_x + v1_y * board.obstacles[k].obstacle_v_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + // # 4 ADDs, 2 MULTs + double r_aB_x = pos_x_i - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + double r_aB_y = pos_y_i - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + + // # 2 MULTs, 1 EXP, 1 DIV + double scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + + // # 2 MULTs + double f_alpha_B_neg_x = r_aB_x * scalar_mult; + double f_alpha_B_neg_y = r_aB_y * scalar_mult; + + double w_val = dt_neg; + double e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -e_y_i : e_y_i); + if (e_dot_f < cos_phi) + w_val = c_neg_times_dt; + + // # 2 MULTs, 2 ADDs + f_alpha_dt_x += f_alpha_B_neg_x * w_val; + f_alpha_dt_y += f_alpha_B_neg_y * w_val; + } + + // # 2 ADDs + w_x[i] += f_alpha_dt_x; + w_y[i] += f_alpha_dt_y; + } + + for (int i = 0; i < n_p_pad; i += 8) { + + __m512d w_x_i_vec = _mm512_loadu_pd(&w_x[i]); + __m512d w_y_i_vec = _mm512_loadu_pd(&w_y[i]); + __m512d v_max_i_vec = _mm512_loadu_pd(&v_max[i]); + __m512d pos_x_i_vec = _mm512_loadu_pd(&pos_x[i]); + __m512d pos_y_i_vec = _mm512_loadu_pd(&pos_y[i]); + __m512d destination_y_i_vec = _mm512_loadu_pd(&destination_y[i]); + __m512d destination_x_i_vec = _mm512_loadu_pd(&destination_x[i]); + __m512d desired_v0_i_vec = _mm512_loadu_pd(&desired_v0[i]); + + __m256i color_i_vec = _mm256_loadu_si256((__m256i *)&color[i]); + + // # 16 MULTs, 8 ADDs + __m512d w_norm_sq = _mm512_fmadd_pd(w_x_i_vec, w_x_i_vec, _mm512_mul_pd(w_y_i_vec, w_y_i_vec)); + + // # 8 SQRTs + __m512d w_norm = _mm512_sqrt_pd(w_norm_sq); + + // # 8 DIVs + __m512d correction_factor = _mm512_min_pd(_mm512_set1_pd(1.0), _mm512_div_pd(v_max_i_vec, w_norm)); + + // # 16 MULTs + __m512d curr_vel_x_i_vec = _mm512_mul_pd(w_x_i_vec, correction_factor); + __m512d curr_vel_y_i_vec = _mm512_mul_pd(w_y_i_vec, correction_factor); + + __m512d dt_vec = _mm512_set1_pd(dt); + + // # 16 MULTs, 16 ADDs + pos_x_i_vec = _mm512_fmadd_pd(curr_vel_x_i_vec, dt_vec, pos_x_i_vec); + pos_y_i_vec = _mm512_fmadd_pd(curr_vel_y_i_vec, dt_vec, pos_y_i_vec); + + __mmask8 cond_1_left = _mm256_cmpeq_epi32_mask(color_i_vec, _mm256_setzero_si256()); + __mmask8 cond_1_right = _mm512_cmp_pd_mask(pos_x_i_vec, _mm512_set1_pd(BOARD_LENGTH_MINUS_ONE_POINT_FIVE), _CMP_GT_OQ); + __mmask8 cond_1 = cond_1_left & cond_1_right; + + pos_x_i_vec = _mm512_mask_blend_pd(cond_1, pos_x_i_vec, _mm512_set1_pd(1.0)); + destination_y_i_vec = _mm512_mask_blend_pd(cond_1, destination_y_i_vec, pos_y_i_vec); + w_x_i_vec = _mm512_mask_blend_pd(cond_1, w_x_i_vec, desired_v0_i_vec); + w_y_i_vec = _mm512_mask_blend_pd(cond_1, w_y_i_vec, _mm512_setzero_pd()); + curr_vel_x_i_vec = _mm512_mask_blend_pd(cond_1, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_pd(cond_1, curr_vel_y_i_vec, w_y_i_vec); + + __mmask8 cond_2_left = _mm256_cmpeq_epi32_mask(color_i_vec, _mm256_set1_epi32(1)); + __mmask8 cond_2_right = _mm512_cmp_pd_mask(pos_x_i_vec, _mm512_set1_pd(1.5), _CMP_LT_OQ); + __mmask8 cond_2 = cond_2_left & cond_2_right; + + pos_x_i_vec = _mm512_mask_blend_pd(cond_2, pos_x_i_vec, _mm512_set1_pd(BOARD_LENGTH - 1.0)); + destination_y_i_vec = _mm512_mask_blend_pd(cond_2, destination_y_i_vec, pos_y_i_vec); + __m512d neg_desired_v0 = _mm512_xor_pd(desired_v0_i_vec, _mm512_set1_pd(-0.0)); + w_x_i_vec = _mm512_mask_blend_pd(cond_2, w_x_i_vec, neg_desired_v0); + w_y_i_vec = _mm512_mask_blend_pd(cond_2, w_y_i_vec, _mm512_setzero_pd()); + curr_vel_x_i_vec = _mm512_mask_blend_pd(cond_2, curr_vel_x_i_vec, w_x_i_vec); + curr_vel_y_i_vec = _mm512_mask_blend_pd(cond_2, curr_vel_y_i_vec, w_y_i_vec); + + pos_y_i_vec = _mm512_max_pd(pos_y_i_vec, _mm512_set1_pd(WALL_EPS)); + pos_y_i_vec = _mm512_min_pd(pos_y_i_vec, _mm512_set1_pd(BOARD_WIDTH_MINUS_WALL_EPS)); + + // # 16 ADDs + __m512d ex_vec = _mm512_sub_pd(destination_x_i_vec, pos_x_i_vec); + __m512d ey_vec = _mm512_sub_pd(destination_y_i_vec, pos_y_i_vec); + + // # 16 MULTs, 8 ADDs + __m512d e_norm_sq = _mm512_fmadd_pd(ex_vec, ex_vec, _mm512_mul_pd(ey_vec, ey_vec)); + + // # 8 SQRTs + __m512d e_norm = _mm512_sqrt_pd(e_norm_sq); + + // # 8 DIVs + __m512d e_norm_inv = _mm512_div_pd(_mm512_set1_pd(1.0), e_norm); + + // # 16 MULT + __m512d e_x_i_vec = _mm512_mul_pd(ex_vec, e_norm_inv); + __m512d e_y_i_vec = _mm512_mul_pd(ey_vec, e_norm_inv); + + // # 16 MULTs, 8 ADDs + __m512d vel_norm_sq = _mm512_fmadd_pd(curr_vel_x_i_vec, curr_vel_x_i_vec, _mm512_mul_pd(curr_vel_y_i_vec, curr_vel_y_i_vec)); + + // # 8 MULTs + __m512d sb_sq_i_vec = _mm512_mul_pd(vel_norm_sq, _mm512_set1_pd(delta_t_sq)); + + // # 8 SQRTs + __m512d vel_norm_dt = _mm512_sqrt_pd(sb_sq_i_vec); + + _mm512_storeu_pd(&curr_vel_x[i], curr_vel_x_i_vec); + _mm512_storeu_pd(&curr_vel_y[i], curr_vel_y_i_vec); + _mm512_storeu_pd(&w_x[i], w_x_i_vec); + _mm512_storeu_pd(&w_y[i], w_y_i_vec); + _mm512_storeu_pd(&pos_x[i], pos_x_i_vec); + _mm512_storeu_pd(&pos_y[i], pos_y_i_vec); + _mm512_storeu_pd(&e_x[i], e_x_i_vec); + _mm512_storeu_pd(&e_y[i], e_y_i_vec); + _mm512_storeu_pd(&destination_y[i], destination_y_i_vec); + _mm512_storeu_pd(&sb_sq[i], sb_sq_i_vec); + + // # 16 MULTs + _mm512_storeu_pd(&sb_e_x[i], _mm512_mul_pd(e_x_i_vec, vel_norm_dt)); + _mm512_storeu_pd(&sb_e_y[i], _mm512_mul_pd(e_y_i_vec, vel_norm_dt)); + } +#if !BENCHMARK + for (int i = 0; i < n_p; i++) { + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, pos_x[i], pos_y[i], e_x[i], e_y[i], color[i]); + } + } +#endif + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +} diff --git a/variants/variant_inlining_8_flopcount.cpp b/variants/variant_inlining_8_flopcount.cpp new file mode 100644 index 0000000..45ffc24 --- /dev/null +++ b/variants/variant_inlining_8_flopcount.cpp @@ -0,0 +1,343 @@ +// # This file performs in-lining for run_simulation. +// # Changes: Replaced references to Vector2d structs inside each Obstacle of Board.obstacles with references to doubles +// # Predecessor: variant_inlining_7.cpp + +#include "../headers/board_reduced.hpp" +#include "../headers/constants.hpp" +#include "../headers/pedestrian_reduced.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEED 42 +#define BOARD_WIDTH 10.0 +#define BOARD_LENGTH 50.0 +#define BOARD_LENGTH_MINUS_ONE BOARD_LENGTH - 1.0 +#define BOARD_LENGTH_MINUS_ONE_POINT_FIVE BOARD_LENGTH - 1.5 +#define WALL_EPS 1e-3 +#define BOARD_WIDTH_MINUS_WALL_EPS 9.999 + +#ifndef RANDOM_SEED +#define RANDOM_SEED 0 +#endif + +#ifndef BENCHMARK +#define BENCHMARK 0 +#endif + +using namespace std; + +Pedestrian *init_pedestrians(int n_p) { +#if RANDOM_SEED + random_device rd; + mt19937 gen(rd()); +#else + mt19937 gen(SEED); +#endif + + normal_distribution velocity_gen(v0_mean, v0_std_dev); + uniform_real_distribution y_gen(0.3, BOARD_WIDTH - 0.3); + uniform_real_distribution x_gen_left(2.0, BOARD_LENGTH / 2.0); + uniform_real_distribution x_gen_right(BOARD_LENGTH / 2.0, BOARD_LENGTH - 2.0); + + Pedestrian *P = new Pedestrian[n_p]; + + int n_p_half = n_p / 2; + + for (int i = 0; i < n_p_half; i++) { + double x = x_gen_left(gen); + double y = y_gen(gen); + + double start_pos_x = x; + double start_pos_y = y; + + double destination_x = BOARD_LENGTH + 30.0; + double destination_y = y; + + double init_e_x = destination_x - start_pos_x; + double init_e_y = destination_y - start_pos_y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + double v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(0, 0, 0, start_pos_x, start_pos_y, init_e_unit_x, init_e_unit_y, v_max, desired_v0, destination_x, destination_y); + } + + for (int i = n_p_half; i < n_p; i++) { + double x = x_gen_right(gen); + double y = y_gen(gen); + + double start_pos_x = x; + double start_pos_y = y; + double destination_x = -30; + double destination_y = y; + + double init_e_x = destination_x - start_pos_x; + double init_e_y = destination_y - start_pos_y; + double init_e_norm = sqrt(init_e_x * init_e_x + init_e_y * init_e_y); + double init_e_unit_x = init_e_x / init_e_norm; + double init_e_unit_y = init_e_y / init_e_norm; + + double desired_v0; + do { + desired_v0 = velocity_gen(gen); + } while (desired_v0 <= 0.1); + + double v_max = 1.3 * desired_v0; + + P[i] = Pedestrian(1, 0, 0, start_pos_x, start_pos_y, init_e_unit_x, init_e_unit_y, v_max, desired_v0, destination_x, destination_y); + } + + return P; +} + +Board init_board_without_obstacles() { return Board(BOARD_LENGTH, BOARD_WIDTH, 0, nullptr); } + +int run_simulation(Pedestrian *pedestrians, Board &board, int n_p, int n_iter, const char *dump_path) { + +#if BENCHMARK + (void)dump_path; +#endif + +#if !BENCHMARK + const int dump_interval = 1; + + vector> samples; + + if (dump_path) { + samples.reserve(static_cast(n_iter / dump_interval + 1) * n_p); + + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + samples.emplace_back(0, i, p.curr_pos_x, p.curr_pos_y, p.e_x, p.e_y, p.color); + } + } +#endif + + // # ADDs: n_iter * n_p * 11 + + // # n_iter * n_p * (n_p - 1) * 14 + + // # n_iter * n_p * board.n_obstacles * 10 + + // # MULTs: n_iter * n_p * 21 + + // # n_iter * n_p * (n_p - 1) * 24 + + // # n_iter * n_p * board.n_obstacles * 13 + + // # DIVs: n_iter * n_p * 2 + + // # n_iter * n_p * (n_p - 1) + + // # n_iter * n_p * board.n_obstacles + + // # SQRTs: n_iter * n_p * 3 + + // # n_iter * n_p * (n_p - 1) * 3 + + // # n_iter * n_p * board.n_obstacles + + // # EXPs: n_iter * n_p * (n_p - 1) + + // # n_iter * n_p * board.n_obstacles + + for (int t = 0; t < n_iter; t++) { + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 2 MULTs + double desired_velocity_x = p.e_x * p.desired_v0; + double desired_velocity_y = p.e_y * p.desired_v0; + + // # 2 MULTs, 2 ADDs + double f_alpha_dt_x = (desired_velocity_x - p.curr_vel_x) * dt_times_tau_alpha_inv; + double f_alpha_dt_y = (desired_velocity_y - p.curr_vel_y) * dt_times_tau_alpha_inv; + + for (int j = 0; j < n_p; j++) { + if (i == j) + continue; + + // # 2 ADDs + double r_ab_x = p.curr_pos_x - pedestrians[j].curr_pos_x; + double r_ab_y = p.curr_pos_y - pedestrians[j].curr_pos_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_ab_norm = sqrt(r_ab_x * r_ab_x + r_ab_y * r_ab_y); + + // # 2 ADDs + double r_ab2_x = r_ab_x - pedestrians[j].s_b_e_x; + double r_ab2_y = r_ab_y - pedestrians[j].s_b_e_y; + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_ab2_norm = sqrt(r_ab2_x * r_ab2_x + r_ab2_y * r_ab2_y); + + // # 1ADD + double r_ab_norm_sum = r_ab_norm + r_ab2_norm; + + // # 1 MULT, 1 ADD + double two_b_sq = r_ab_norm_sum * r_ab_norm_sum - pedestrians[j].s_b_sq; + + // # 1 SQRT + double two_b = sqrt(two_b_sq); + + // # 5 MULTs, 1 EXP, 1 DIV + double scalar_mult_common = (r_ab_norm_sum / (two_b * r_ab_norm * r_ab2_norm)) * (NEG_V0_AB_div_TWO_SIGMA * exp(two_b * NEG_TWO_SIGMA_INV)); + + // # 2 MULTs + double scalar_mult_r_ab = scalar_mult_common * r_ab2_norm; + double scalar_mult_r_ab2 = scalar_mult_common * r_ab_norm; + + // # 4 MULTs, 2 ADDs + double f_alpha_beta_neg_x = r_ab_x * scalar_mult_r_ab + r_ab2_x * scalar_mult_r_ab2; + double f_alpha_beta_neg_y = r_ab_y * scalar_mult_r_ab + r_ab2_y * scalar_mult_r_ab2; + + double w_val; + + // # 3 MULTs, 1 ADD + double a = (p.e_x * f_alpha_beta_neg_x + p.e_y * f_alpha_beta_neg_y) * cos_phi_inv; + + // # 2 MULTs, 1 ADD + double b_sq = f_alpha_beta_neg_x * f_alpha_beta_neg_x + f_alpha_beta_neg_y * f_alpha_beta_neg_y; + + w_val = dt_neg; + + // # 1 MULT + if (a >= 0 && (a * a > b_sq)) { + w_val = c_neg_times_dt; + } + + // # 2 MULTs, 2 ADDs + f_alpha_dt_x = f_alpha_dt_x + f_alpha_beta_neg_x * w_val; + f_alpha_dt_y = f_alpha_dt_y + f_alpha_beta_neg_y * w_val; + } + + for (int k = 0; k < board.n_obstacles; k++) { + + // # 2 ADDs + double v1_x = p.curr_pos_x - board.obstacles[k].start_x; + double v1_y = p.curr_pos_y - board.obstacles[k].start_y; + + // # 3 MULTs, 1 ADD + double projection = (v1_x * board.obstacles[k].obstacle_v_x + v1_y * board.obstacles[k].obstacle_v_y) * board.obstacles[k].length_sq_inv; + + if (projection < 0.0) + projection = 0.0; + else if (projection > 1.0) + projection = 1.0; + + // # 4 ADDs, 2 MULTs + double r_aB_x = p.curr_pos_x - (board.obstacles[k].start_x + board.obstacles[k].obstacle_v_x * projection); + double r_aB_y = p.curr_pos_y - (board.obstacles[k].start_y + board.obstacles[k].obstacle_v_y * projection); + + // # 1 SQRT, 2 MULTs, 1 ADD + double r_aB_norm = sqrt(r_aB_x * r_aB_x + r_aB_y * r_aB_y); + // # 4 MULTs, 1 EXP, 1 DIV + double scalar_mult = (NEG_U0_AB_div_R * exp(r_aB_norm * NEG_R_INV)) / r_aB_norm; + double f_alpha_B_neg_x = r_aB_x * scalar_mult; + double f_alpha_B_neg_y = r_aB_y * scalar_mult; + + double w_val; + double e_dot_f = (f_alpha_B_neg_y == 0) ? 0 : (f_alpha_B_neg_y < 0 ? -p.e_y : p.e_y); + if (e_dot_f >= cos_phi) + w_val = dt_neg; + else + w_val = c_neg_times_dt; + + // # 2 MULTs + double f_alpha_B_dt_x = f_alpha_B_neg_x * w_val; + double f_alpha_B_dt_y = f_alpha_B_neg_y * w_val; + + // # 2 ADDs + f_alpha_dt_x += f_alpha_B_dt_x; + f_alpha_dt_y += f_alpha_B_dt_y; + } + + // # 2 ADDs + p.w_x += f_alpha_dt_x; + p.w_y += f_alpha_dt_y; + } + + for (int i = 0; i < n_p; i++) { + Pedestrian &p = pedestrians[i]; + + // # 1 SQRT, 2 MULTs, 1 ADD + double w_norm = sqrt(p.w_x * p.w_x + p.w_y * p.w_y); + + // # 1 DIV + double correction_factor = min(1.0, p.v_max / w_norm); + + // # 2 MULTs + p.curr_vel_x = p.w_x * correction_factor; + p.curr_vel_y = p.w_y * correction_factor; + + // # 2 MULTs, 2 ADDs + p.curr_pos_x = p.curr_pos_x + p.curr_vel_x * dt; + p.curr_pos_y = p.curr_pos_y + p.curr_vel_y * dt; + + if (p.color == 0 && p.curr_pos_x > BOARD_LENGTH_MINUS_ONE_POINT_FIVE) { + p.curr_pos_x = 1.0; + p.destination_y = p.curr_pos_y; + p.w_x = p.desired_v0; + p.w_y = 0.0; + p.curr_vel_x = p.w_x; + p.curr_vel_y = p.w_y; + } + if (p.color == 1 && p.curr_pos_x < 1.5) { + p.curr_pos_x = BOARD_LENGTH_MINUS_ONE; + p.destination_y = p.curr_pos_y; + p.w_x = -p.desired_v0; + p.w_y = 0.0; + p.curr_vel_x = p.w_x; + p.curr_vel_y = p.w_y; + } + + p.curr_pos_y = clamp(p.curr_pos_y, WALL_EPS, BOARD_WIDTH_MINUS_WALL_EPS); + + // # 2 ADDs + double e_x = p.destination_x - p.curr_pos_x; + double e_y = p.destination_y - p.curr_pos_y; + + // # 1 DIV, 1 SQRT, 2 MULTs, 1 ADD + double e_norm_inv = 1.0 / sqrt(e_x * e_x + e_y * e_y); + + // # 2 MULTs + p.e_x = e_x * e_norm_inv; + p.e_y = e_y * e_norm_inv; + + // # 2 MULTs, 1 ADD + double velocity_norm_sq = p.curr_vel_x * p.curr_vel_x + p.curr_vel_y * p.curr_vel_y; + + // # 1 SQRT + double velocity_norm = sqrt(velocity_norm_sq); + + // # 5 MULTs + p.s_b_sq = velocity_norm_sq * delta_t_sq; + p.s_b_e_x = p.e_x * (velocity_norm * delta_t); + p.s_b_e_y = p.e_y * (velocity_norm * delta_t); + +#if !BENCHMARK + if (dump_path && (t % dump_interval == 0)) { + samples.emplace_back(t + 1, i, p.curr_pos_x, p.curr_pos_y, p.e_x, p.e_y, p.color); + } +#endif + } + } + +#if !BENCHMARK + if (dump_path) { + ofstream out(dump_path); + out << "time,id,x,y,p.e.x,p.e.y,color\n"; + + for (auto &[t, id, x, y, e_x, e_y, c] : samples) { + out << t << ',' << id << ',' << x << ',' << y << ',' << e_x << ',' << e_y << ',' << c << '\n'; + } + } +#endif + + return 0; +}