[clean-list] Why drastically different performance of these two
implementations?
David C. Norris
David_Norris at brown.edu
Wed Dec 19 20:00:39 MET 2007
I would like to understand why 'iconvolve' below performs so much worse
than 'convolve'. How might one speed up iconvolve, while still
preserving its pattern of traversal of arrays a and b?
David
-----
module myconvolve
import StdEnv
// When compiled with clm -fusion, this implementation proves to be
// marginally faster than gcc -O2 compiled C using nested for loops
// as in:
// for(i=0; i++, i<na){
// for(j=0; j++, j<nb){
// ab[i+j] += a[i] * b[j];
// }
// }
convolve :: (ar e) (ar e) -> (ar e) | Array ar e & Arith e
convolve a b = {let start = max 0 (i-m)
end = min i n
in
foldl (+) zero [ a.[i-k] * b.[k] \\ k <-
[start..end] ]
\\ i <- [0..(m+n)]}
where
m = size a - 1
n = size b - 1
// Why does this implementation (imitating the C algorithm above) run
30x slower?
iconvolve :: !{#Real} !{#Real} -> {#Real}
iconvolve a b = iconvolve` ab 0 0 0
where
na = size a
nb = size b
nab = na + nb - 1
ab = createArray nab 0.0
iconvolve` ab=:{[k]=ab_k} i j k // constraint k==i+j is maintained
| i >= na = ab
| j >= nb = iconvolve` ab (i+1) 0 (i+1)
| otherwise = iconvolve` ab` i (j+1) (i+j+1)
where
ab` = {ab & [k] = ab_k + a.[i] * b.[j]}
Start :: Real
//Start = (iconvolve a b).[m+n-2]
Start = (convolve a b).[m+n-2]
where
m = 10000
n = 6000
a :: {#Real}
a = {fromInt x \\ x <- [1..m]}
b :: {#Real}
b = {fromInt x \\ x <- [1..n]}
More information about the clean-list
mailing list