Wyniki benchmarków kilku implementacji sumy kroczącej kwadratów (MSS):

  • algorytm szeregowy, na podstawie funkcji z SleepECG
    • MSSi,k=MSSi1,k+xi+k122xik212MSS_{i,k} = MSS_{i-1,k} + x_{i+ \lfloor \frac{k-1}{2} \rfloor }^2 - x_{i - \lfloor \frac{k}{2} \rfloor - 1}^2,
    • Work=O(n)Work = O(n),
    • Span=O(n)Span = O(n),
  • algorytm równoległy, ale nieefektywny względem algorytmu szeregowego
    • MSSi,k=j=ik2i+k12xj2MSS_{i,k} = \sum_{j=i-\lfloor \frac{k}{2} \rfloor}^{i+ \lfloor \frac{k-1}{2} \rfloor} x_j^2,
    • Work=O(nk)Work = O(n\,k),
    • Span=O(k)Span = O(k),

gdzie n to długość sygnału, k – długość okna i 0<kn0 < k \leq n.

Kod źródłowy:

Benchmarki wykonano na Intel® Core™ i7-12700 z 16 GiB RAM-u i AMD Radeon™ RX 6600 XT. Typ danych: float64.

  • Futhark: 0.25.22. Backendy: C, Multicore, OpenCL (GPU).
  • Julia: 1.10.5.
  • Mojo: 24.4.
  • Elixir: 1.16.2. Erlang: 26.2.5. Backend: EXLA (CPU, JIT).
  • C++: GCC 14.2.1, OpenMP: 4.5 (CPU), ArrayFire: 3.9.0 (OpenCL, GPU).

Średni czas wykonania w zależności od długości sygnału dla okna o długości 32 próbek

Szeregowy

Długość sygnału [próbki]MojoC++Futhark CJuliaElixir EXLA
2 0481,7 μs1,7 μs2,0 μs2,2 μs22 μs
4 0963,4 μs3,5 μs3,8 μs4,4 μs50 μs
8 1926,9 μs6,9 μs7,4 μs8,7 μs69 μs
16 38414 μs14 μs15 μs17 μs0,12 ms
32 76827 μs27 μs29 μs34 μs0,29 ms
65 53655 μs55 μs58 μs69 μs0,53 ms
131 0720,11 ms0,11 ms0,12 ms0,14 ms1,0 ms
262 1440,22 ms0,22 ms0,23 ms0,28 ms1,9 ms
524 2880,44 ms0,44 ms0,46 ms0,59 ms3,9 ms
1 048 5760,88 ms0,89 ms0,97 ms1,2 ms7,2 ms
2 097 1521,8 ms1,9 ms2,0 ms2,4 ms15 ms
4 194 3043,8 ms3,9 ms4,0 ms4,8 ms28 ms
8 388 6087,8 ms7,8 ms7,9 ms9,5 ms56 ms
16 777 21616 ms16 ms16 ms19 ms0,11 s
33 554 43231 ms31 ms32 ms38 ms0,22 s
67 108 86462 ms62 ms62 ms76 ms-

Równoległy (CPU)

Długość sygnału [próbki]JuliaC++ OpenMPMojoFuthark MulticoreElixir EXLA
2 04814 μs15 μs6,0 μs9,0 μs22 μs
4 09616 μs16 μs7,3 μs13 μs27 μs
8 19219 μs18 μs8,5 μs21 μs42 μs
16 38418 μs22 μs13 μs35 μs68 μs
32 76830 μs29 μs20 μs80 μs0,15 ms
65 53639 μs43 μs38 μs0,12 ms0,28 ms
131 07281 μs73 μs71 μs0,11 ms0,46 ms
262 1440,13 ms0,13 ms0,14 ms0,21 ms0,79 ms
524 2880,27 ms0,25 ms0,27 ms0,39 ms1,5 ms
1 048 5760,66 ms0,51 ms0,54 ms0,78 ms3,1 ms
2 097 1521,3 ms1,2 ms1,1 ms2,2 ms6,1 ms
4 194 3043,0 ms3,4 ms4,1 ms5,5 ms12 ms
8 388 6085,7 ms6,8 ms8,2 ms11 ms23 ms
16 777 21611 ms14 ms16 ms22 ms43 ms
33 554 43225 ms26 ms32 ms43 ms75 ms
67 108 86445 ms51 ms65 ms84 ms-

Równoległy (GPU)

Długość sygnału [próbki]Futhark (OpenCL)C++ ArrayFire (OpenCL)
2 04830 μs28 μs
4 09630 μs28 μs
8 19230 μs29 μs
16 38432 μs31 μs
32 76836 μs37 μs
65 53644 μs44 μs
131 07250 μs59 μs
262 14473 μs88 μs
524 2880,11 ms0,15 ms
1 048 5760,19 ms0,27 ms
2 097 1520,47 ms0,66 ms
4 194 3041,0 ms1,3 ms
8 388 6081,9 ms2,6 ms
16 777 2163,9 ms4,9 ms
33 554 4327,7 ms9,9 ms
67 108 86415 ms19 ms

Średni czas wykonania w zależności od długości okna dla sygnału o długości 50⋅10⁶ próbek

Szeregowy

Długość okna [próbki]C++MojoFuthark CJuliaElixir EXLA
146 ms47 ms47 ms56 ms0,17 s
246 ms47 ms47 ms57 ms0,24 s
447 ms46 ms46 ms57 ms0,34 s
846 ms46 ms47 ms57 ms0,32 s
1646 ms46 ms47 ms57 ms0,32 s
3246 ms47 ms47 ms56 ms0,35 s
6446 ms46 ms46 ms57 ms0,35 s
12846 ms46 ms46 ms57 ms0,40 s
25646 ms46 ms46 ms56 ms0,64 s
51246 ms46 ms47 ms57 ms0,97 s
1 02446 ms46 ms47 ms57 ms1,7 s
2 04846 ms47 ms47 ms57 ms2,9 s

Równoległy (CPU)

Długość okna [próbki]JuliaC++ OpenMPMojo (CPU)Elixir EXLAFuthark Multicore
129 ms32 ms34 ms35 ms55 ms
229 ms33 ms36 ms77 ms57 ms
430 ms33 ms39 ms79 ms59 ms
833 ms34 ms37 ms88 ms60 ms
1631 ms36 ms42 ms0,11 s60 ms
3234 ms39 ms48 ms0,11 s64 ms
6441 ms50 ms62 ms0,16 s0,10 s
12853 ms76 ms98 ms0,20 s0,22 s
25678 ms0,12 s0,17 s0,34 s0,44 s
5120,17 s0,24 s0,32 s0,62 s0,88 s
1 0240,26 s0,45 s0,61 s1,2 s1,7 s
2 0480,51 s0,85 s1,2 s2,3 s3,5 s

Równoległy (GPU)

Długość okna [próbki]C++ ArrayFire (OpenCL)Futhark (OpenCL)
17,4 ms7,3 ms
27,6 ms7,4 ms
47,7 ms7,3 ms
88,1 ms7,3 ms
1610,0 ms8,2 ms
3214 ms11 ms
6424 ms18 ms
12843 ms30 ms
2560,17 s55 ms
5120,17 s0,10 s
1 0240,17 s0,20 s
2 0480,17 s0,40 s

Zwięzłość kodu źródłowego

ImplementacjaLiczba tokenów bez białych znakówRozmiar po skompresowaniu (LZMA) [B]
Futhark szeregowy278434
Futhark równoległy109266
Julia szeregowy208472
Julia równoległy132409
C++ szeregowy347593
C++ równoległy (CPU)254629
C++ równoległy (GPU)138422
Elixir+Nx szeregowy431713
Elixir+Nx równoległy145424
Mojo szeregowy353565
Mojo równoległy249540