JuliaSIMD / JuliaSIMD/LoopVectorization.jl

Plain for loop faster than @turbo

未关闭
#449 5 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Julia
星标
789
派生
73
PR 合并指标
30 天内没有已合并 PR

描述

Consider the following:

```julia
using LoopVectorization, StrideArraysCore, BenchmarkTools

randn_stridearray(size...) = StrideArray(randn(Float32, size...), static.(size))

y = randn_stridearray(64, 32, 256);
x = randn_stridearray(64, 32, 256);
b = randn_stridearray(32);

function foo!(y, x, b)
@turbo for i in axes(y, 1), c in axes(y, 2), n in axes(y, 3)
y[i, c, n] = x[i, c, n] + b[c]
end
return nothing
end

function foo2!(y, x, b)
for n in axes(y, 3)
@turbo for i in axes(y, 1), c in axes(y, 2)
y[i, c, n] = x[i, c, n] + b[c]
end
end
return nothing
end
```

I would expect `foo2` to perform slightly worse or the same as `foo`.
However, the result is

```
julia> @btime foo!($y, $x, $b)
153.958 μs (0 allocations: 0 bytes)

julia> @btime foo2!($y, $x, $b)
51.583 μs (0 allocations: 0 bytes)
```

What is happening here? Am I doing something wrong?
If it matters: I am running this on an Apple M1.

Edit:

A plain for loop is about as fast as `foo2!`:

```
julia> function foo3!(y, x, b)
for n in axes(y, 3)
for c in axes(y, 2)
for i in axes(y, 1)
y[i, c, n] = x[i, c, n] + b[c]
end
end
end
return nothing
end
foo3! (generic function with 1 method)

julia> @btime foo3!($y, $x, $b)
52.375 μs (0 allocations: 0 bytes)
```

贡献指南

这个仓库没有索引到贡献指南

调研方向

首先,使用所示的 Julia、LoopVectorization、StrideArraysCore 和 BenchmarkTools 配置,重现 issue 中报告的 foo!、foo2! 和 foo3! 的耗时。比较三种循环形式生成的行为或基准测试结果;当性能差异得到解释并确定所需的项目变更后,调查即告完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
julia
领域
performance
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
需要澄清
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。