小编Bra*_*rdy的帖子

当我删除边界检查时,为什么我的代码运行速度较慢?

我在Rust写了一个线性代数库.

我有一个函数来获取给定行和列的矩阵单元格的引用.此函数以一对断言开始,行和列在边界内:

#[inline(always)]
pub fn get(&self, row: usize, col: usize) -> &T {
    assert!(col < self.num_cols.as_nat());
    assert!(row < self.num_rows.as_nat());
    unsafe {
        self.get_unchecked(row, col)
    }
}
Run Code Online (Sandbox Code Playgroud)

在紧密的循环中,我认为跳过边界检查可能会更快,所以我提供了一个get_unchecked方法:

#[inline(always)]
pub unsafe fn get_unchecked(&self, row: usize, col: usize) -> &T {
    self.data.get_unchecked(self.row_col_index(row, col))
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,当我使用这些方法来实现矩阵乘法(通过行和列迭代器)时,我的基准测试显示,当我检查边界时它实际上快了大约33%.为什么会这样?

我在两台不同的计算机上试过这个,一台运行Linux,另一台运行OSX,两者都显示效果.

完整的代码在github上.相关文件是lib.rs.感兴趣的功能是:

  • get 在第68行
  • get_unchecked 在第81行
  • next 在第551行
  • mul 在第796行
  • matrix_mul (基准)在第1038行

请注意,我正在使用类型级数来参数化我的矩阵(通过虚拟标记类型也可以选择动态大小),因此基准测试将两个100x100矩阵相乘.

更新:

我已经大大简化了代码,删除了在基准测试中没有直接使用的东西并删除了泛型参数.我还编写了一个不使用迭代器的乘法实现,并且该版本不会产生相同的效果.有关此版本的代码,请参见此处.克隆minimal-performance分支并运行cargo bench将对两种不同的乘法实现进行基准测试(请注意,断言在该分支中以注释开头).

另外值得注意的是,如果我更改get*函数以返回数据的副本而不是引用(f64而不是&f64 …

optimization performance rust llvm-codegen

26
推荐指数
1
解决办法
740
查看次数

如何在Haskell中为软实时应用程序优化垃圾收集?

我在Haskell编写了一个软实时应用程序,它处理模拟物理,碰撞检测,所有这些好东西.在做所有这些事情的时候,我分配了大量的内存,如果我愿意的话,我可能会优化我的内存使用量,但是因为我很好地使用了40%的CPU并且只使用了1%的RAM,所以这似乎没有必要.我所看到的是,很多时候,当垃圾收集器启动时,帧被跳过.我已经通过以下方式验证了这是问题的原因threadscope:当垃圾收集器完成其业务时,有时不会有有效的计算时间达到0.05秒,导致最多3个跳帧,这非常明显且非常烦人.

现在,我尝试通过手动调用performMinorGC每一帧来解决这个问题,这似乎可以缓解这个问题,使其更加平滑,除了整体CPU使用率急剧上升到70%左右.显然我宁愿避免这种情况.

我尝试的另一件事是使用-H64k将GC的分配空间从512k降低到64k,我还尝试设置-I0.03以尝试让它更频繁地收集.这两个选项都改变了我看到的垃圾收集模式threadscope,但它们仍然导致跳过帧.

任何有GC优化经验的人都可以帮助我吗?我是否注定要手动调用performMinorGC并忍受导致的巨大性能损失?

编辑

我尝试在这些测试中运行它的时间相似,但是因为它是实时的,所以它没有"完成".

performMinorGC每4帧运行时统计信息:

     9,776,109,768 bytes allocated in the heap
     349,349,800 bytes copied during GC
      53,547,152 bytes maximum residency (14 sample(s))
      12,123,104 bytes maximum slop
             105 MB total memory in use (0 MB lost due to fragmentation)

                                     Tot time (elapsed)  Avg pause  Max pause
  Gen  0     15536 colls, 15536 par    3.033s   0.997s     0.0001s    0.0192s
  Gen  1        14 colls,    13 par    0.207s   0.128s     0.0092s    0.0305s

  Parallel GC work balance: …
Run Code Online (Sandbox Code Playgroud)

optimization garbage-collection haskell

15
推荐指数
1
解决办法
354
查看次数

是否有可能在没有功能扩展性的情况下证明Agda中类别类别(带有仿函数作为态射)的存在?

我正在建模这样的类别和仿函数(导入来自标准库):

module Categories where

open import Level
open import Relation.Binary.PropositionalEquality

record Category a b  : Set (suc (a ? b)) where
  field
    Obj : Set a
    _?_ : Obj ? Obj ? Set b
    _?_ : {A B C : Obj} ? B ? C ? A ? B ? A ? C
    id : {A : Obj} ? A ? A

    left-id : ? {A B : Obj} (f : A ? B) ? id ? f ? f …
Run Code Online (Sandbox Code Playgroud)

agda category-theory

2
推荐指数
1
解决办法
100
查看次数