हम अपने अधिकांश सीपीयू चक्रों को छोटे मैट्रिस से जुड़े संचालन पर खर्च करते हैं, इसलिए मुझे आश्चर्य हुआ कि क्या उस मामले के लिए अनुकूलित करना संभव था।छोटे मैट्रिक्स के लिए एचमैट्रिक्स से शुद्ध हास्केल 10x-100x तेज?
module Main where
import Numeric.LinearAlgebra.HMatrix
import Criterion.Main
data Matrix2x2 = Matrix2x2 {-# UNPACK #-} !Double !Double !Double !Double
mul2x2p :: Matrix2x2 -> Matrix2x2 -> Matrix2x2
mul2x2p (Matrix2x2 a1 b1 c1 d1) (Matrix2x2 a2 b2 c2 d2) =
Matrix2x2 (a1*a2 + b1*c2) (a1*b2 + b1*d2) (c1*a2 + d1*c2) (c1*b2 + d1*d2)
inv2x2 :: Matrix2x2 -> Matrix2x2
inv2x2 (Matrix2x2 a b c d) =
let detInv = a * d - b * c
in Matrix2x2 (d/detInv) (-b/detInv) (-c/detInv) (a/detInv)
add2x2 (Matrix2x2 a1 b1 c1 d1) (Matrix2x2 a2 b2 c2 d2) =
Matrix2x2 (a1+a2) (b1+b2) (c1+c2) (d1+d2)
hm1 = matrix 2 [1, 2, 3, 4]
hm2 = matrix 2 [5, 6, 7, 8]
pm1 = Matrix2x2 1 2 3 4
pm2 = Matrix2x2 5 6 7 8
main = defaultMain [
bgroup "matrix tests" [ bench "pure mult" $ whnf (mul2x2p pm1) pm2
, bench "hmatrix mult" $ whnf (hm1 <>) hm2
, bench "pure add" $ whnf (add2x2 pm1) pm2
, bench "hmatrix add" $ whnf (hm1 +) hm2
, bench "pure inv" $ whnf inv2x2 pm1
, bench "hmatrix inv" $ whnf inv hm1
]]
परिणाम::
benchmarking matrix tests/pure mult
time 6.461 ns (6.368 ns .. 6.553 ns)
0.999 R² (0.998 R² .. 0.999 R²)
mean 6.482 ns (6.394 ns .. 6.594 ns)
std dev 345.1 ps (271.4 ps .. 477.3 ps)
variance introduced by outliers: 77% (severely inflated)
benchmarking matrix tests/hmatrix mult
time 180.6 ns (178.2 ns .. 183.1 ns)
0.999 R² (0.998 R² .. 0.999 R²)
mean 183.0 ns (180.6 ns .. 186.3 ns)
std dev 9.363 ns (7.405 ns .. 12.73 ns)
variance introduced by outliers: 71% (severely inflated)
benchmarking matrix tests/pure add
time 6.262 ns (6.223 ns .. 6.297 ns)
0.999 R² (0.999 R² .. 1.000 R²)
mean 6.281 ns (6.220 ns .. 6.355 ns)
std dev 235.0 ps (183.3 ps .. 321.0 ps)
variance introduced by outliers: 62% (severely inflated)
benchmarking matrix tests/hmatrix add
time 116.4 ns (115.0 ns .. 117.9 ns)
0.999 R² (0.998 R² .. 0.999 R²)
mean 116.3 ns (115.2 ns .. 117.7 ns)
std dev 4.176 ns (3.447 ns .. 5.150 ns)
variance introduced by outliers: 55% (severely inflated)
benchmarking matrix tests/pure inv
time 7.811 ns (7.718 ns .. 7.931 ns)
0.999 R² (0.998 R² .. 0.999 R²)
mean 7.895 ns (7.808 ns .. 7.988 ns)
std dev 296.4 ps (247.2 ps .. 358.3 ps)
variance introduced by outliers: 62% (severely inflated)
benchmarking matrix tests/hmatrix inv
time 908.5 ns (901.3 ns .. 916.6 ns)
0.999 R² (0.998 R² .. 0.999 R²)
mean 934.0 ns (917.6 ns .. 961.3 ns)
std dev 73.92 ns (50.53 ns .. 108.6 ns)
variance introduced by outliers: 84% (severely inflated)
मेरे प्रश्न हैं:
1) गति को असली है या बेंच मार्किंग प्रक्रिया के साथ एक विरूपण साक्ष्य की वजह से है निम्नलिखित कोड पर विचार करें?
2) यदि गति वास्तविक है, तो क्या मौजूदा पुस्तकालय है जो 1x1, 2x2, 3x3, 4x4 matrices को विशेष मामलों के रूप में संभालेगा?
3) यदि नहीं, तो एचमैट्रिक्स को लपेटने का सबसे अच्छा तरीका क्या है ताकि मैट्रिक्स छोटा होने पर हम तेज़ पथ ले सकें? ghc केवल एक कन्स्ट्रक्टर के साथ रिकॉर्ड अनपैक कर सकते हैं। वहाँ एक रास्ता अपने आप हमारे कोड के विभिन्न संस्करणों उत्पन्न करने के लिए, आदि है
उदाहरण-test.cabal:
name: example-test
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.10
executable example-test
main-is:
Main.hs
build-depends:
base >=4.7 && <4.8,
criterion,
hmatrix
default-language:
Haskell2010
ghc-options:
-H12G -O3 -optc-O3 -fllvm -rtsopts -threaded -fexcess-precision -j6 +RTS -N6 -RTS -fno-ignore-asserts -fcontext-stack=150
-- -fforce-recomp
तुम समझ रहे हो क्या "गंभीर रूप से फुलाया" का अर्थ है? –
@ बार्टेकबानाकाइज: यह एक उत्कृष्ट बिंदु है, और मैं आमतौर पर इसे स्वयं कहता हूं, लेकिन मुझे संदेह है कि इन परिणामों पर इसका असर पड़ता है।प्रदर्शन अंतर बहुत बड़ा है; हैमट्रिक्स 200 से अधिक std विचलन दूर है –
हालांकि, "गंभीर रूप से फुलाया" कभी-कभी मानदंड बेंचमार्क के साथ कुछ गलत संकेतक हो सकता है, इसलिए यह एक वैध चिंता है। –