github - gonum - BLAS - norm

收錄在 Ameba 的 100 篇

--
前篇 github 提交 floats.Norm 之後,

開始有了討論,
https://github.com/gonum/gonum/pull/1131 - 原本我提的
https://github.com/gonum/gonum/pull/1132 - BLAS Dnrm2
https://github.com/gonum/gonum/pull/1134 - 用 BLAS Dnrm2 搬到 internal asm 中


BLAS 是 Basic Linear Algebra Subprograms的意思
原作是 Basic Linear Algebra Subgrograms For Fortran Usage
是 1979 年 由 C. L. Lawson, R. J. Hanson, D. R. Kincaid and F. T. Krogh 所撰寫

原來 Fortran 還活著, 2013 年, Intel 還有這篇文章:
  Improving Numerical Reproducibility in C/C++/Fortran

我們看三個的狀況 s[0], s[1], s[2], 假設 s[0] < s[1] < s[2]
Loop 1: i==0
     sumeSqures = 1
     scale = s[0]
Loop 2: i==1
     sumSqures = 1 + (s[0]/s[1])^2
     scale = s[1]
Loop 3 : i==2
     sumSqures = 1+ (1 + (s[0]/s[1])^2) * (s[1]/s[2])^2) = 1 + (s[1]/s[2])^2 + (s[0]/s[2])^2
     scale = s[2]

最後回傳值 = scale * sqrt(sumSquares) = sqrt( scale^2 * sumSqures)
= sqrt(s[2]^2 + s[1]^2 + s[0]^2)
即為所求

和原本方式比較, 這方式不用每個項目做一次開根號動作, 又不是單純的平方和,
有效地避免了 overflow/underflow 的問題

Benchmark

實驗後 benchmark_test.og
這方式可以比原本快四倍, 果然底層沒寫好的話,
對整體效能影響很大

Distance 14028379 80.6 ns/op
Your Distance 51248080 21.8 ns/op




這方式往下搬到了 f32 和 f64 中, 即
https://github.com/gonum/gonum/pull/1134
f32.L2NormInc(x, uintptr(n), uintptr(incX)
f64.L2NormInc(x, uintptr(n), uintptr(incX)

至於為什麼會看到 gonum, 是因為最近看的這本
Machine Learning with GO

github.com 的確是個不錯的交流管道, pull request 設計也挺有趣
是時候回來看看 emgo egc 如何 compile 加上 Ameba 平台
    https://github.com/ziutek/emgo
最近用這 emgo 開發 cortex-m embedded system 也變多了
    https://linux.cn/article-11383-1.html
這篇也值得好好看看, 複習一下 compiler
    How a GO program compiles down to a Machine Code




留言

熱門文章