- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在努力优化我的 Julia 代码并使其运行得更快。
我抽象了我的整个代码的一部分,我希望你评估是否存在一些瓶颈,使过程比优化的过程慢。
代码的简要说明:
array1
n x n 数组,用 randn
随机条目初始化array1
将在循环中的某个算法下更新,直到array1
的所有条目将大于 -0.8
using Random;
function Test()
n=5
sqn = n^2
foo1 = circshift(collect(1:n)', (0, 1))
foo2 = circshift(collect(1:n)', (0, -1))
foo3 = circshift(collect(1:n), 1)
foo4 = circshift(collect(1:n), -1)
# initialize array1 with random entries
array1 = randn(n,n);
# initialize array2 with zeros
array2 = zeros(n,n);
#println(array1);
loop = 0
while minimum(array1) < -0.8 && loop < 100000
loop += 1
bar = zeros(n, n)
# Use simd?
for i = 1:sqn
bar[i] = max(0, array1[i] - 0.2)
end
array2 += bar
adding = zeros(n, n)
# Use simd?
for i = 1:n
for j = 1:n
adding[i, j] =
(1 / 4) * sum([
bar[i, foo1[j]],
bar[i, foo2[j]],
bar[foo3[i], j],
bar[foo4[i], j],
])
end
end
array1 = array1 - bar + adding
end
# println(array1)
# println(array2)
# println(loop)
end
Test()
我想我可以使用
@simd
来节省时间在一些
for statement
.
SIMD
以外的任何有用信息,我会很高兴听到它。
最佳答案
是的,尤其是使用 LoopVectorization.jl -- 尽管还有一些其他优化我们必须先做,然后才能进入球场,这是限制因素。
首先,使用 BenchmarkTools.jl 在我的系统(一台旧笔记本电脑)上的代码的一些初始计时
julia> using BenchmarkTools
julia> @benchmark Test()
BechmarkTools.Trial: 31 samples with 1 evaluations.
Range (min … max): 5.987 μs … 257.525 ms ┊ GC (min … max): 0.00% … 22.07%
Time (median): 234.396 ms ┊ GC (median): 16.67%
Time (mean ± σ): 162.310 ms ± 114.023 ms ┊ GC (mean ± σ): 18.44% ± 8.84%
█ ▂
█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅█▅██▁▃ ▁
5.99 μs Histogram: frequency by time 258 ms <
Memory estimate: 9.84 KiB, allocs estimate: 70.
循环仅在几十次评估中短路的情况与运行完整 100000 次的情况之间似乎存在一些明显的双峰性。顺便说一句,这是一个典型的例子,说明为什么尽管有一些传统智慧,最小次数不是一个很好的基准测试指标,意味着或(甚至更好)完整直方图要好得多——所以来自
BenchmarkTools.jl 的直方图或
BenchmarkHistograms.jl很棒。
function test()
n=5
sqn = n^2
r = collect(1:n)
foo1 = circshift(r', (0, 1))
foo2 = circshift(r', (0, -1))
foo3 = circshift(r, 1)
foo4 = circshift(r, -1)
# initialize array1 with random entries
array1 = randn(n,n);
# initialize array2 with zeros
array2 = zeros(n,n);
# Initialize temporary arrays used in loops
bar = zeros(n, n)
adding = zeros(n, n)
loop = 0
while minimum(array1) < -0.8 && loop < 100000
loop += 1
fill!(bar, 0)
# Use simd?
@inbounds for i = 1:sqn
bar[i] = max(0, array1[i] - 0.2)
end
@. array2 += bar
fill!(adding, 0)
# Use simd?
@inbounds for i = 1:n
for j = 1:n
s = bar[i, foo1[j]] + bar[i, foo2[j]] + bar[foo3[i], j] + bar[foo4[i], j]
adding[i, j] = 0.25 * s
end
end
@. array1 = array1 - bar + adding
end
return array1, array2, loop
end
如您所见,我移动了
bar
的分配。和
adding
在循环之外——因为它们不会改变大小,我们可以只分配它们一次,然后在必要时重新填充零。另一个更改涉及在添加和减去数组时不必要的分配分配。原版
array1 = array1 - bar + adding
例如正在分配,但
@. array1 = array1 - bar + adding
,这只是
array1 .= array1 .- bar .+ adding
的便捷简写, 明确表示我们需要逐元素操作,并将确保它们都就地发生(即,不会触发新的堆分配)。我也放了一个
@inbounds
在
for
循环并稍微重构最内层循环中的求和(虽然
sum
很快,但不是如评论中所述,分配一个全新的数组以在循环的每次迭代中相加)。
julia> @benchmark test()
BechmarkTools.Trial: 305 samples with 1 evaluations.
Range (min … max): 1.622 μs … 30.093 ms ┊ GC (min … max): 0.00% … 0.00%
Time (median): 22.438 ms ┊ GC (median): 0.00%
Time (mean ± σ): 16.429 ms ± 11.530 ms ┊ GC (mean ± σ): 0.00% ± 0.00%
█ ▁
█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▇▄▃▃▄▃▅▅▂▃▃▂▃▂ ▂
1.62 μs Histogram: frequency by time 29.4 ms <
Memory estimate: 1.75 KiB, allocs estimate: 9.
现在是 SIMD。原来只是加上
@inbounds @simd
在 for 循环前面没有出现在启用 Julia 编译器尚未找到的任何优化的计时中。
LoopVectorization的
@turbo
但是:
using Random, LoopVectorization
function test_simd_turbo()
n=5
sqn = n^2
r = collect(1:n)
foo1 = circshift(r', (0, 1))
foo2 = circshift(r', (0, -1))
foo3 = circshift(r, 1)
foo4 = circshift(r, -1)
# initialize array1 with random entries
array1 = randn(n,n);
# initialize array2 with zeros
array2 = zeros(n,n);
# Initialize temporary arrays used in loops
bar = zeros(n, n)
adding = zeros(n, n)
loop = 0
while minimum(array1) < -0.8 && loop < 100000
loop += 1
fill!(bar, 0)
# Use simd?
@turbo for i = 1:sqn
bar[i] = max(0, array1[i] - 0.2)
end
@turbo @. array2 += bar
fill!(adding, 0)
# Use simd?
@turbo for i = 1:n
for j = 1:n
s = bar[i, foo1[j]] + bar[i, foo2[j]] + bar[foo3[i], j] + bar[foo4[i], j]
adding[i, j] = 0.25 * s
end
end
@turbo @. array1 = array1 - bar + adding
end
return array1, array2, loop
end
请注意,您可以使用
@turbo
对两者进行 SIMD 向量化
for
循环和
@.
广播,如这里所见。
julia> @benchmark test_simd_turbo()
BechmarkTools.Trial: 419 samples with 1 evaluations.
Range (min … max): 1.864 μs … 28.059 ms ┊ GC (min … max): 0.00% … 0.00%
Time (median): 15.486 ms ┊ GC (median): 0.00%
Time (mean ± σ): 11.946 ms ± 8.034 ms ┊ GC (mean ± σ): 0.00% ± 0.00%
█
█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▇▇▆▅▄▄▃▄▄▄▃▃▂▁▂▁▁▁▂▁▁▁▁▁▁▃ ▂
1.86 μs Histogram: frequency by time 26.3 ms <
Memory estimate: 1.75 KiB, allocs estimate: 9.
LoopVectorization.jl 的优势在具有
AVX512 的系统上可能会更大。矢量寄存器(我在这台笔记本电脑上只有 AVX2)。
关于arrays - Julia 代码优化 : is this the time to use SIMD?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67857312/
在尝试 time 的 python 执行时,我发现在一条语句中两次调用 time.time() 时出现奇怪的行为。在语句执行期间获取time.time() 有一个非常小的处理延迟。 例如time.ti
我要疯了。对于我的生活,我无法弄清楚为什么以下代码会导致 Unity 在我按下播放键后立即卡住。这是一个空的项目,脚本附加到一个空的游戏对象。在控制台中,什么也没有出现,甚至没有出现初始的 Debug
我要疯了。对于我的生活,我无法弄清楚为什么以下代码会导致 Unity 在我按下播放键后立即卡住。这是一个空的项目,脚本附加到一个空的游戏对象。在控制台中,什么也没有出现,甚至没有出现初始的 Debug
我不明白为什么下面的结果是一样的。我预计第一个结果是指针地址。 func print(t *time.Time) { fmt.Println(t) // 2009-11-10 23:00:00
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)] on win32 Type "help
当我有一个time.Time时: // January, 29th t, _ := time.Parse("2006-01-02", "2016-01-29") 如何获得代表 1 月 31 日的 ti
首先,我意识到不推荐使用 time with time zone。我要使用它是因为我将多个 time with time zone 值与我当前的系统时间进行比较,而不管是哪一天。 IE。用户说每天 0
长期以来,在 Rust 中精确测量时间的标准方法是 time crate 及其 time::precise_time_ns功能。但是,time crate 现在已被弃用,std 库有 std::tim
我正在我学校的一个科学集群上运行我的有限差分程序。该程序使用 openmpi 来并行化代码。 当程序连续运行时,我得到: real 78m40.592s user 78m34.920s s
尽管它们已被弃用并且有比 time 更好的模块(即 timeit),但我想知道这两个函数 time 之间的区别.clock() 和 time.time()。 从后者 (time.time()) 开始,
这个问题在这里已经有了答案: Python's time.clock() vs. time.time() accuracy? (16 个答案) 关闭 6 年前。 我认为两者都衡量时间量?但是他们返回
我正在尝试测试 http 请求处理代码块在我的 Flask Controller 中需要多长时间,这是我使用的示例代码: cancelled = [] t0 = time.time() t1 = ti
运行 python 的计算机时钟(Windows 或 Linux)时会发生什么自动更改并调用 time.time()? 我读到,当时钟手动更改为过去的某个值时,time.time() 的值会变小。 最
我有一个结构可能无法在其字段之一上设置 time.Time 值。测试无效性时,我不能使用 nil 或 0。time.Unix(0,0) 也不相同。我想到了这个: var emptyTime time.
我有一个打算用数据库记录填充的结构,其中一个日期时间列可以为空: type Reminder struct { Id int CreatedAt time.Time
问题陈述:通过匹配其百分比随机执行各种命令。比如执行 CommandA 50% 的时间和 commandB 25% 的时间和 commandC 15% 的时间等等,总百分比应该是 100%。 我的问题
我正在使用 laravel 6。我在同一个应用程序中有类似的 Controller 和类似的 View ,它工作正常。对比之后还是找不到错误。 Facade\Ignition\Exceptions\V
我需要用 ("%m/%d/%Y %H:%M:%S") 格式表示时间,我得到的浮点值是 time.time(). 我已经有了一个 time.time() 形式的值。例如,我已经有一个值,我每 0.3 秒
我正在使用以下方法获取 utc 日期时间: import datetime import time from pytz import timezone now_utc = datetime.datet
我在 Ubuntu 上使用 time.clock 和 time.time 为一段 python 代码计时: clock elapsed time: 8.770 s time elapsed time
我是一名优秀的程序员,十分优秀!