OK, wow! I tried following the advice in
https://github.com/staticfloat/homebrew-julia
specifically,
$ brew rm gcc openblas-julia suite-sparse-julia arpack-julia
$ brew install gcc openblas-julia suite-sparse-julia arpack-julia
Now, there is a difference: the non-SIMD version is *much slower* than
before:
GFlop = 0.39122184254142406
GFlop (SIMD) = 1.7337076986157214
The SIMD version is basically the same speed as before, but according to
code_llvm there is no vectorization.
I think I need to lie down.
Here's the code_llvm outputs:
*julia> **code_llvm(innersimd, Tuple{Vector{Float32},Vector{Float32}})*
define float @julia_innersimd_21416(%jl_value_t*, %jl_value_t*) {
L:
%2 = bitcast %jl_value_t* %0 to %jl_array_t*
%3 = getelementptr inbounds %jl_array_t* %2, i32 0, i32 1
%4 = load i64* %3
%5 = icmp sle i64 1, %4
%6 = xor i1 %5, true
%7 = select i1 %6, i64 0, i64 %4
%8 = insertvalue %UnitRange.1 { i64 1, i64 undef }, i64 %7, 1
%9 = extractvalue %UnitRange.1 %8, 1
%10 = load %jl_value_t** @jl_overflow_exception
%11 = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 %9, i64 1)
%12 = extractvalue { i64, i1 } %11, 1
%13 = xor i1 %12, true
br i1 %13, label %pass, label %fail
fail: ; preds = %L
call void @jl_throw_with_superfluous_argument(%jl_value_t* %10, i32 67)
unreachable
pass: ; preds = %L
%14 = extractvalue { i64, i1 } %11, 0
%15 = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %14, i64 1)
%16 = extractvalue { i64, i1 } %15, 1
%17 = xor i1 %16, true
br i1 %17, label %pass2, label %fail1
fail1: ; preds = %pass
call void @jl_throw_with_superfluous_argument(%jl_value_t* %10, i32 67)
unreachable
pass2: ; preds = %pass
%18 = extractvalue { i64, i1 } %15, 0
%19 = icmp slt i64 0, %18
%20 = xor i1 %19, true
br i1 %20, label %L11, label %L5.preheader
L5.preheader: ; preds = %pass2
%sunkaddr = ptrtoint %jl_value_t* %0 to i64
%sunkaddr19 = inttoptr i64 %sunkaddr to i8**
%21 = load i8** %sunkaddr19
%sunkaddr20 = ptrtoint %jl_value_t* %1 to i64
%sunkaddr21 = inttoptr i64 %sunkaddr20 to i8**
%22 = load i8** %sunkaddr21
br label %L5
L5: ; preds = %L5, %L5.
preheader
%lsr.iv16 = phi i8* [ %22, %L5.preheader ], [ %scevgep17, %L5 ]
%lsr.iv = phi i8* [ %21, %L5.preheader ], [ %scevgep, %L5 ]
%"##i#7098.0" = phi i64 [ %27, %L5 ], [ 0, %L5.preheader ]
%s.1 = phi float [ %26, %L5 ], [ 0.000000e+00, %L5.preheader ]
%lsr.iv1618 = bitcast i8* %lsr.iv16 to float*
%lsr.iv15 = bitcast i8* %lsr.iv to float*
%23 = load float* %lsr.iv15
%24 = load float* %lsr.iv1618
%25 = fmul float %23, %24
%26 = fadd fast float %s.1, %25
%27 = add i64 %"##i#7098.0", 1
%scevgep = getelementptr i8* %lsr.iv, i64 4
%scevgep17 = getelementptr i8* %lsr.iv16, i64 4
%28 = icmp slt i64 %27, %18
br i1 %28, label %L5, label %L11
L11: ; preds = %L5, %pass2
%s.3 = phi float [ 0.000000e+00, %pass2 ], [ %26, %L5 ]
ret float %s.3
}
*julia> **code_llvm(inner, Tuple{Vector{Float32},Vector{Float32}})*
define float @julia_inner_21415(%jl_value_t*, %jl_value_t*) {
top:
%2 = bitcast %jl_value_t* %0 to %jl_array_t*
%3 = getelementptr inbounds %jl_array_t* %2, i32 0, i32 1
%4 = load i64* %3
%5 = icmp sle i64 1, %4
%6 = xor i1 %5, true
%7 = select i1 %6, i64 0, i64 %4
%8 = insertvalue %UnitRange.1 { i64 1, i64 undef }, i64 %7, 1
%9 = extractvalue %UnitRange.1 %8, 1
%10 = add i64 %9, 1
%11 = icmp eq i64 1, %10
br i1 %11, label %L3, label %L.preheader
L.preheader: ; preds = %top
%12 = bitcast %jl_value_t* %0 to %jl_array_t*
%13 = bitcast %jl_array_t* %12 to i8**
%14 = load i8** %13
%15 = bitcast %jl_value_t* %1 to %jl_array_t*
%16 = bitcast %jl_array_t* %15 to i8**
%17 = load i8** %16
%18 = add i64 %9, -1
br label %L
L: ; preds = %L, %L.preheader
%lsr.iv6 = phi i8* [ %14, %L.preheader ], [ %scevgep7, %L ]
%lsr.iv4 = phi i8* [ %17, %L.preheader ], [ %scevgep, %L ]
%lsr.iv = phi i64 [ %18, %L.preheader ], [ %lsr.iv.next, %L ]
%s.0 = phi float [ %22, %L ], [ 0.000000e+00, %L.preheader ]
%lsr.iv68 = bitcast i8* %lsr.iv6 to float*
%lsr.iv45 = bitcast i8* %lsr.iv4 to float*
%19 = load float* %lsr.iv68
%20 = load float* %lsr.iv45
%21 = fmul float %19, %20
%22 = fadd float %s.0, %21
%23 = icmp eq i64 %lsr.iv, 0
%24 = xor i1 %23, true
%lsr.iv.next = add i64 %lsr.iv, -1
%scevgep = getelementptr i8* %lsr.iv4, i64 4
%scevgep7 = getelementptr i8* %lsr.iv6, i64 4
br i1 %24, label %L, label %L3
L3: ; preds = %L, %top
%s.1 = phi float [ 0.000000e+00, %top ], [ %22, %L ]
ret float %s.1
}