# CAS benchmarks (Symbolics.jl and Maxima)

**URL:** <https://discourse.julialang.org/t/cas-benchmarks-symbolics-jl-and-maxima/58359>\
**Category:** Performance\
**Tags:** symbolic\
**Created:** [April 1, 2021, 12:24am UTC](https://discourse.julialang.org/t/cas-benchmarks-symbolics-jl-and-maxima/58359 "2021-04-01T00:24:24Z")\
**Posts on this page:** 1\
**Showing post:** 15

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [April 2, 2021, 4:02pm UTC](https://discourse.julialang.org/t/cas-benchmarks-symbolics-jl-and-maxima/58359/15 "2021-04-02T16:02:23Z")

</div>

Not explicitly SIMD for a single evaluation (because the idea is still that you’d SIMD across multiple evaluations), but `SLEEFPirates.estrin` uses the estrin method, scaling much better for multiple evaluations:

```julia
julia> coef = ntuple(_ -> randn(), Val(30));

julia> packed = packpoly1x4r(coef);

julia> @btime evalpoly1x4r($(Ref(1.2))[], $packed)
  4.644 ns (0 allocations: 0 bytes)
-204.5524827611573

julia> @btime SLEEFPirates.estrin($(Ref(1.2))[], $coef)
  5.437 ns (0 allocations: 0 bytes)
-204.5524827611573

julia> @btime evalpoly($(Ref(1.2))[], $coef)
  12.540 ns (0 allocations: 0 bytes)
-204.5524827611572

```

But SIMDPoly won for all the numbers of coefficients I tried when it comes to speeding up a single evaluation.

> [@rfateman](#):
>
> There is some ambiguity in your post. If the line in the program is presented to a compiler as  
> ’ evalpoly(1.0, (1,2,3))’ then the only code that is needed to be generated is ‘return 6.0’.
> 
> If the line in the program is 'evalpoly(1.0, ) ’ then it can’t be unrolled at compile time. Are you saying that at run-time, the program is unrolled? That seems wasteful.

Types are known at compile time, so in that example what was known is `evalpoly(::Int, ::NTuple{3,Int})`.  
If we define a function `f` such that everything is known:

```julia
julia> f() = evalpoly(1.0, (1,2,3))
f (generic function with 1 method)

julia> @code_typed f()
CodeInfo(
1 ─ return 6.0
) => Float64

```

If we make the coefficients known:

```julia
julia> f(x) = evalpoly(x, (1,2,3))
f (generic function with 2 methods)

julia> @code_typed f(2)
CodeInfo(
1 ─ %1 = Base.mul_int(x, 3)::Int64
│ %2 = Base.add_int(%1, 2)::Int64
│ %3 = Base.mul_int(x, %2)::Int64
│ %4 = Base.add_int(%3, 1)::Int64
└── return %4
) => Int64

```

Etc.

If the number of coefficients is unknown but large, the compiler would unroll by some constant amount (dependent on the particular machine it’s compiling for) to make good use of the CPU’s execution resources.

---

_[View the full topic](https://discourse.julialang.org/t/cas-benchmarks-symbolics-jl-and-maxima/58359)._
