* Comments welcomed to progr. style / speed of my first ocaml program "Error correcting LDPC decoder"
@ 2005-12-15 10:33 Andries Hekstra
[not found] ` <OFB50A01B3.ECDA5A94-ONC12570D8.00394FEA-C12570D8.003A2427@philips.com >
2005-12-16 19:35 ` Jon Harrop
0 siblings, 2 replies; 5+ messages in thread
From: Andries Hekstra @ 2005-12-15 10:33 UTC (permalink / raw)
To: caml-list
[-- Attachment #1.1: Type: text/plain, Size: 1277 bytes --]
Dear All,
I am an applied scientist in the areas of signal processing and error
correction at Philips Research. Having done the programming work of my
computer simulations in C/C++ for almost 10-15 years with increasingly
mixed feelings about the languange, a friend pointed me to functional
programming. This way I found ocaml and I must say I am very enthusiastic
about it. The built-in arrays, the functions that are really meta
functions and remove a lot of tedious programming and debugging. Also the
combined availability of an interpreter and compiler is comforbable and
not unlike matlab (which I hate).
I am also intrigued by the promise of functional languages when multi-core
computers will be the defacto standard.
Attached please find the first program I wrote. It has about the same
speed as its C++ counterpart (slightly faster). I welcome comments w.r.t.
programming style, esp. when it affects the speed of the program.
Regards,
Andries Hekstra
------------------------------------------------------------------------
Dr. Ir. Andries P. Hekstra
Philips Research
High Tech Campus 37
5656 AG Eindhoven
Tel./Fax/Secr. +31 40 27 42048/42566/44051
If you need anti-RSI break software : Look at http://www.workrave.org
(good and for free)
[-- Attachment #1.2: Type: text/html, Size: 1628 bytes --]
[-- Attachment #2: Main.ml --]
[-- Type: application/octet-stream, Size: 16249 bytes --]
(* Parameters of the LDPC code, left and right degree*)
let ldpc_j = 3
let ldpc_k = 30
let codeRate = 1. -. float_of_int ldpc_j /. float_of_int ldpc_k
let targetCodewordLength = (ldpc_k * 300)
let blockSize = targetCodewordLength / ldpc_k
let codewordLength = blockSize * ldpc_k
let numberOfParityChecks = blockSize * ldpc_j
let fudgeFactor = 0.75
let maxNumberOfIterations = 30
;;
print_string "LDPC decoder for rate 1 - ";
print_int ldpc_j;
print_string "/";
print_int ldpc_k;
print_string " Gallager code with length ";
print_int codewordLength;
flush stdout
;;
(* Construction of a sparse parity check matrix*)
let height a = Array.length a
let width a = Array.length a.(0)
let applyToMatrix f a =
let rec applyToMatrixAux i j f a =
if (i >= 0) then begin
a.(i).(j) <- f i j a.(i).(j);
if (j-1 >= 0)
then applyToMatrixAux i (j-1) f a
else applyToMatrixAux (i-1) (width a - 1) f a
end
in applyToMatrixAux (height a - 1) (width a - 1) f a
let order = Array.create_matrix ldpc_j codewordLength 0
let permutation = Array.create_matrix ldpc_j codewordLength 0
;;
applyToMatrix (fun j -> fun i -> fun x -> (Random.int (100 * codewordLength))) order;;
applyToMatrix (fun j -> fun i -> fun x -> i) permutation;;
let swapElement i j a = let x = a.(i) in a.(i) <- a.(j); a.(j) <- x
let qsort op a =
let l = Array.length a in
let rec qsortAux i j op a =
if (i < j) then begin
let x = a.((i + j) / 2) in
let i1 = ref i in
let j1 = ref j in
while (!i1 <= !j1) do
while (op a.(!i1) x) do incr i1 done;
while (op x a.(!j1)) do decr j1 done;
if (i1 <= j1) then begin
swapElement !i1 !j1 a;
incr i1;
decr j1
end
done;
qsortAux !i1 j op a;
qsortAux i !j1 op a;
end
in qsortAux 0 (l - 1) op a;;
let qsort2 op a b =
let l = Array.length a in
let rec qsort2Aux i j op a b =
if (i < j) then begin
let x = a.((i + j) / 2) in
let i1 = ref i in
let j1 = ref j in
while (!i1 <= !j1) do
while (op a.(!i1) x) do incr i1 done;
while (op x a.(!j1)) do decr j1 done;
if (i1 <= j1) then begin
swapElement !i1 !j1 a;
swapElement !i1 !j1 b;
incr i1;
decr j1
end
done;
qsort2Aux !i1 j op a b;
qsort2Aux i !j1 op a b;
end
in qsort2Aux 0 (l - 1) op a b;;
let sortRows a =
let rec sortRowsAux i a = if (i >= 0) then begin qsort (<) a.(i); sortRowsAux (i-1) a end
in sortRowsAux (Array.length a - 1) a
let sortRows2 a b =
let rec sortRows2Aux i a b = if (i >= 0) then begin qsort2 (<) a.(i) b.(i); sortRows2Aux (i-1) a b end
in sortRows2Aux (Array.length a - 1) a b;;
sortRows2 order permutation;;
let inversePermutation = Array.create_matrix ldpc_j codewordLength 0;;
for j = 0 to ldpc_j - 1 do
for i = 0 to codewordLength - 1 do
inversePermutation.(j).(permutation.(j).(i)) <- i
done
done;;
let oneColumnInRow = Array.create_matrix numberOfParityChecks ldpc_k 0;;
let jOneColumnInRow = Array.create_matrix numberOfParityChecks ldpc_k 0;;
(* Here, i indexes parity checks *)
applyToMatrix (fun i -> fun k -> fun x -> inversePermutation.(i / blockSize).(k + ldpc_k * (i mod blockSize))) oneColumnInRow;;
applyToMatrix (fun i -> fun k -> fun x -> i / blockSize) jOneColumnInRow;;
sortRows2 oneColumnInRow jOneColumnInRow;;
let oneRowInColumn = Array.create_matrix codewordLength ldpc_j 0;;
let kOneRowInColumn = Array.create_matrix codewordLength ldpc_j 0;;
for j = 0 to ldpc_j-1 do
for r = 0 to blockSize -1 do
let i = r + j * blockSize in
for k = 0 to ldpc_k-1 do
oneRowInColumn .(oneColumnInRow.(i).(k)).(j) <- i;
kOneRowInColumn.(oneColumnInRow.(i).(k)).(j) <- k;
done
done
done;;
sortRows2 oneRowInColumn kOneRowInColumn;;
let numberOfColumnPairsWithOverlap = ref 0;;
for i1 = 0 to codewordLength - 1 do
for i2 = 0 to i1-1 do
let overlap = ref 0 in begin
for j1 = 0 to ldpc_j-1 do
for j2 = 0 to ldpc_j-1 do
if (oneRowInColumn.(i1).(j1) = oneRowInColumn.(i2).(j2)) then incr overlap;
done
done;
if (!overlap > 1) then incr numberOfColumnPairsWithOverlap;
end
done
done;;
print_string "\nnumberOfColumnPairsWithOverlap = ";;
print_int !numberOfColumnPairsWithOverlap;;
(* Random bit vector *)
let bitArrayFromInt n iii =
let rec bitArrayFromIntAux i n iii =
if (i < n) then
Array.append [| (iii mod 2) |] (bitArrayFromIntAux (i+1) n (iii / 2))
else [||]
in bitArrayFromIntAux 0 n iii
let makeRandomBit a =
let rec makeRandomBitAux i a =
if (i > 0) then begin
let b = bitArrayFromInt 8 (Random.int 256) in
let i1 = ref i in
let count = ref 0 in begin
while (!i1 >= 0) & (!count < 8) do
a.(!i1) <- b.(!count);
decr i1;
incr count;
done;
makeRandomBitAux !i1 a
end
end
in makeRandomBitAux (Array.length a - 1) a
(* Normal distribution *)
let randomGaussian sigma =
let u1 = Random.float 1. in
let u2 = Random.float 1. in
let r = sqrt (-2. *. log (u1)) in
let pi = 2. *. asin 1. in
let phi = 2. *. pi *. u2
in sigma *. r *. cos (phi)
(* Message passing functions *)
let sum a = let rec sum i a = if (i > 0) then a.(i) +. sum (i-1) a else if (i = 0) then a.(i) else 0.
in sum ((Array.length a) - 1) a
let hardBit softBit = if (softBit >= 0.) then 0 else 1
let reliability softBit = if (softBit >= 0.) then softBit else (-. softBit)
(* LDPC decode *)
let softBitOut channelLLR1 messageSymbolNodeIn1 = channelLLR1 +. sum messageSymbolNodeIn1
let hardBitOut channelLLR1 messageSymbolNodeIn1 = hardBit (softBitOut channelLLR1 messageSymbolNodeIn1)
let processCheckNode channelLLR
oneColumnInRow
jOneColumnInRow
syndrome
messagesSymbolNodeIn
messageCheckNodeIn
messageCheckNodeOut =
let messageSymbolNodeOut channelLLR1 messageSymbolNodeIn1 j =
(softBitOut channelLLR1 messageSymbolNodeIn1) -. messageSymbolNodeIn1.(j) in begin
(* Get the input messages to the current check node *)
for k = 0 to ldpc_k-1 do
messageCheckNodeIn.(k) <- fudgeFactor *.
(messageSymbolNodeOut channelLLR.(oneColumnInRow.(k))
messagesSymbolNodeIn.(oneColumnInRow.(k))
jOneColumnInRow.(k))
done;
(* Compute the total EXOR, the min. and second min. reliability and the index *)
let k1 = ref 0 in
let minReliability1 = ref 1e10 in
let minReliability2 = ref 1e10 in
let totalExor = ref syndrome in begin
for k = 0 to ldpc_k-1 do
totalExor := !totalExor + hardBit messageCheckNodeIn.(k);
let h = reliability messageCheckNodeIn.(k) in
if !minReliability1 >= h then begin
minReliability2 := !minReliability1;
minReliability1 := h;
k1 := k;
end else begin
if !minReliability2 >= h then minReliability2 := h
end
done;
totalExor := !totalExor mod 2;
(* Compute the output messages *)
for k = 0 to ldpc_k-1 do
let h = if k = !k1 then !minReliability2 else !minReliability1 in
if ((!totalExor + (hardBit messageCheckNodeIn.(k))) mod 2) = 0 then
messageCheckNodeOut.(k) <- h
else
messageCheckNodeOut.(k) <- (-. h)
done;
(* Assign the output messages *)
for k = 0 to ldpc_k-1 do
messagesSymbolNodeIn.(oneColumnInRow.(k)).(jOneColumnInRow.(k)) <- messageCheckNodeOut.(k);
done;
(!totalExor = 0)
end
end
let ldpcDecode transmittedCodeword
syndrome
channelLLR
decodedCodeword
oneColumnInRow
jOneColumnInRow
messagesSymbolNodeIn
numberOfIterations =
let messageCheckNodeIn = Array.create ldpc_k 0. in
let messageCheckNodeOut = Array.create ldpc_k 0. in
let allZeroesSyndrome = ref false in begin
numberOfIterations := 0;
while (!numberOfIterations < maxNumberOfIterations) & not !allZeroesSyndrome do
allZeroesSyndrome := true;
for row = 0 to numberOfParityChecks - 1 do
if not (processCheckNode channelLLR
oneColumnInRow.(row)
jOneColumnInRow.(row)
syndrome.(row)
messagesSymbolNodeIn
messageCheckNodeIn
messageCheckNodeOut) then
allZeroesSyndrome := false;
done;
incr numberOfIterations;
done;
let numberOfBitErrors = ref 0 in begin
for column = 0 to codewordLength - 1 do
decodedCodeword.(column) <- hardBitOut channelLLR.(column) messagesSymbolNodeIn.(column);
if (decodedCodeword.(column) <> transmittedCodeword.(column)) then
incr numberOfBitErrors;
done;
!numberOfBitErrors;
end
end
(* Simulation parameters *)
let ebOverNoDbLow = 3.4
let ebOverNoDbHigh = 4.
(*let ebOverNoDbLow = 10.0
let ebOverNoDbHigh = 10.0*)
let ebOverNoDbStep = 0.1
let numberOfCodewordsToSimulate = 30000
let ebOverNoDb = ref ebOverNoDbLow
let totalNumberOfFrameErrors = ref 1
;;
while (!ebOverNoDb <= ebOverNoDbHigh) & (!totalNumberOfFrameErrors > 0) do
print_string "\n\nEbOverNoDb = ";
print_float !ebOverNoDb;
print_string ", time = ";
print_float (Sys.time());
print_string " seconds!\n";
flush stdout;
let ebOverNo = 10. ** (!ebOverNoDb /. 10.) in
let lc = 4. *. ebOverNo *. codeRate in
let sigmaNoise = 1. /. sqrt (2. *. ebOverNo *. codeRate) in
let totalNumberOfChannelBitErrors = ref 0. in
let totalNumberOfBits = ref 0. in
let totalNumberOfDecodedBitErrors = ref 0. in
let totalNumberOfFrames = ref 0 in
let totalNumberOfIterations = ref 0. in
let transmittedCodeword = Array.create codewordLength 0 in
let decodedCodeword = Array.create codewordLength 0 in
let syndrome = Array.create numberOfParityChecks 0 in
let channelLLR = Array.create codewordLength 0. in
let messagesSymbolNodeIn = Array.create_matrix codewordLength ldpc_j 0. in begin
totalNumberOfFrameErrors := 0;
while (!totalNumberOfFrames < numberOfCodewordsToSimulate)
& ((!totalNumberOfDecodedBitErrors < 500.) or (!totalNumberOfFrameErrors < 200)) do
makeRandomBit transmittedCodeword;
for r = 0 to numberOfParityChecks-1 do
syndrome.(r) <- 0;
for k = 0 to ldpc_k-1 do
syndrome.(r) <- ((syndrome.(r) + transmittedCodeword.(oneColumnInRow.(r).(k))) mod 2)
done
done;
for i = 0 to codewordLength - 1 do
channelLLR.(i) <- float_of_int (1 - 2*transmittedCodeword.(i)) +. randomGaussian sigmaNoise
done;
let numberOfChannelBitErrors = ref 0 in begin
for i = 0 to codewordLength-1 do
if transmittedCodeword.(i) <> hardBit channelLLR.(i) then incr numberOfChannelBitErrors
done;
totalNumberOfChannelBitErrors := !totalNumberOfChannelBitErrors +. float_of_int !numberOfChannelBitErrors;
totalNumberOfBits := !totalNumberOfBits +. float_of_int codewordLength;
end;
let numberOfIterations = ref 0 in
let numberOfDecodedBitErrors = ldpcDecode transmittedCodeword
syndrome
channelLLR
decodedCodeword
oneColumnInRow
jOneColumnInRow
messagesSymbolNodeIn
numberOfIterations in begin
totalNumberOfDecodedBitErrors := !totalNumberOfDecodedBitErrors +. float_of_int numberOfDecodedBitErrors;
totalNumberOfIterations := !totalNumberOfIterations +. float_of_int !numberOfIterations;
if numberOfDecodedBitErrors > 0 then incr totalNumberOfFrameErrors;
incr totalNumberOfFrames;
end;
if (!totalNumberOfFrames mod 100) = 0 then begin
let avgChannelBER = !totalNumberOfChannelBitErrors /. !totalNumberOfBits in
let avgDecodedBER = !totalNumberOfDecodedBitErrors /. !totalNumberOfBits in
let avgFER = float_of_int !totalNumberOfFrameErrors /. float_of_int !totalNumberOfFrames in
let avgIter = !totalNumberOfIterations /. float_of_int !totalNumberOfFrames in
begin
print_int !totalNumberOfFrames;
print_string "\tChannelBER = ";
print_float avgChannelBER;
print_string "\tDecodedBER = ";
print_float avgDecodedBER;
print_string "\tFER = ";
print_float avgDecodedBER;
print_string "\tavgIter = ";
print_float avgIter;
print_string "\n";
flush stdout;
end
end
done
end;
ebOverNoDb := !ebOverNoDb +. ebOverNoDbStep;
done;;
print_string "\n\nSuccesful completion in ";;
print_float (Sys.time());;
print_string " seconds!\n";;
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Comments welcomed to progr. style / speed of my first ocaml program "Error correcting LDPC decoder"
[not found] ` <OFB50A01B3.ECDA5A94-ONC12570D8.00394FEA-C12570D8.003A2427@philips.com >
@ 2005-12-15 12:03 ` Gerd Stolpmann
2005-12-15 12:40 ` Gerd Stolpmann
0 siblings, 1 reply; 5+ messages in thread
From: Gerd Stolpmann @ 2005-12-15 12:03 UTC (permalink / raw)
To: Andries Hekstra; +Cc: caml-list
Andries Hekstra said:
> Attached please find the first program I wrote. It has about the same
> speed as its C++ counterpart (slightly faster). I welcome comments w.r.t.
> programming style, esp. when it affects the speed of the program.
As you are doing a lot of array manipulation, this tip may increase
performance significantly: because "float array" is stored with a
different layout than all other arrays, the compiler generates a dynamic
check for every access when the type of the array elements cannot be
statically determined. For example, your function
let swapElement i j a = let x = a.(i) in a.(i) <- a.(j); a.(j) <- x
is polymorphic in the element type. If you define instead
let swapFloatElement i j (a : float array) =
let x = a.(i) in a.(i) <- a.(j); a.(j) <- x
better code is generated because the mentioned check can be omitted by the
compiler. This applies only if the function is not inlined; swapElement
could be small enough (but qsort, for instance, is definitely not).
Unfortunately, one cannot define swapNonFloatElement because there is no
way to constrain a type that it is not float. So the type system cannot
represent this duality float/non-float, and one must fall back to as many
definitions as element types are actually used.
Gerd
------------------------------------------------------------
Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany
gerd@gerd-stolpmann.de http://www.gerd-stolpmann.de
------------------------------------------------------------
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Comments welcomed to progr. style / speed of my first ocaml program "Error correcting LDPC decoder"
2005-12-15 12:03 ` [Caml-list] " Gerd Stolpmann
@ 2005-12-15 12:40 ` Gerd Stolpmann
2005-12-15 15:09 ` Xavier Leroy
0 siblings, 1 reply; 5+ messages in thread
From: Gerd Stolpmann @ 2005-12-15 12:40 UTC (permalink / raw)
To: Gerd Stolpmann; +Cc: Andries Hekstra, caml-list
I forgot one thing: This comment is only correct for 32 bit code. 64 bit
code has a uniform array layout for all element types.
Gerd
Gerd Stolpmann said:
>
> Andries Hekstra said:
>> Attached please find the first program I wrote. It has about the same
>> speed as its C++ counterpart (slightly faster). I welcome comments
>> w.r.t.
>> programming style, esp. when it affects the speed of the program.
>
> As you are doing a lot of array manipulation, this tip may increase
> performance significantly: because "float array" is stored with a
> different layout than all other arrays, the compiler generates a dynamic
> check for every access when the type of the array elements cannot be
> statically determined. For example, your function
>
> let swapElement i j a = let x = a.(i) in a.(i) <- a.(j); a.(j) <- x
>
> is polymorphic in the element type. If you define instead
>
> let swapFloatElement i j (a : float array) let x = a.(i) in a.(i) <-
> a.(j); a.(j) <- x
>
> better code is generated because the mentioned check can be omitted by the
> compiler. This applies only if the function is not inlined; swapElement
> could be small enough (but qsort, for instance, is definitely not).
>
> Unfortunately, one cannot define swapNonFloatElement because there is no
> way to constrain a type that it is not float. So the type system cannot
> represent this duality float/non-float, and one must fall back to as many
> definitions as element types are actually used.
>
> Gerd
> ------------------------------------------------------------
> Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany
> gerd@gerd-stolpmann.de http://www.gerd-stolpmann.de
> ------------------------------------------------------------
>
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>
------------------------------------------------------------
Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany
gerd@gerd-stolpmann.de http://www.gerd-stolpmann.de
------------------------------------------------------------
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Comments welcomed to progr. style / speed of my first ocaml program "Error correcting LDPC decoder"
2005-12-15 12:40 ` Gerd Stolpmann
@ 2005-12-15 15:09 ` Xavier Leroy
0 siblings, 0 replies; 5+ messages in thread
From: Xavier Leroy @ 2005-12-15 15:09 UTC (permalink / raw)
To: Gerd Stolpmann; +Cc: caml-list
> I forgot one thing: This comment is only correct for 32 bit code. 64 bit
> code has a uniform array layout for all element types.
Yes, but a generic access to a float array still involves an extra
boxing operation. So, your advice is sound for 64-bit plaforms as well.
I had a very quick look at the original poster's code: it seems
reasonable performance-wise. There are a few extra hacks that could
be done to increase performance at some expense in code clarity, for
instance turning
a.(i).(j) <- f i j a.(i).(j);
in
(let b = a.(i) in b.(j) <- f i j b.(j));
but I wouldn't recommend doing this unless profiling exhibits a big
"hot spot" in this function.
- Xavier Leroy
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Comments welcomed to progr. style / speed of my first ocaml program "Error correcting LDPC decoder"
2005-12-15 10:33 Comments welcomed to progr. style / speed of my first ocaml program "Error correcting LDPC decoder" Andries Hekstra
[not found] ` <OFB50A01B3.ECDA5A94-ONC12570D8.00394FEA-C12570D8.003A2427@philips.com >
@ 2005-12-16 19:35 ` Jon Harrop
1 sibling, 0 replies; 5+ messages in thread
From: Jon Harrop @ 2005-12-16 19:35 UTC (permalink / raw)
To: caml-list
On Thursday 15 December 2005 10:33, Andries Hekstra wrote:
> I am an applied scientist in the areas of signal processing and error
> correction at Philips Research. Having done the programming work of my
> computer simulations in C/C++ for almost 10-15 years with increasingly
> mixed feelings about the languange, a friend pointed me to functional
> programming.
You may be interested in my book Objective CAML for Scientists:
http://www.ffconsultancy.com/products/ocaml_for_scientists
It covers everything you need and is written for people with similar
backgrounds to your own.
> I welcome comments w.r.t. programming style, esp. when it affects the speed
> of the program.
You don't need to use ";;" in compiled source.
You can replace:
print_string "LDPC decoder for rate 1 - ";
print_int ldpc_j;
print_string "/";
print_int ldpc_k;
print_string " Gallager code with length ";
print_int codewordLength;
flush stdout
with a call to "Printf.printf".
You can replace:
fun j -> fun i -> fun x ->
with
fun j i x ->
Try to avoid superfluous parentheses:
if (i < j) then begin
Use Array.sort instead of writing your own "qsort". Use an array of 2-tuples
(pairs) instead of two arrays and a custom "qsort2" function.
Put a space either side of a bracketed prefix operator, to avoid problems with
(*):
qsort (<) a.(i)
Coalesce computations into a single "let () = ...", rather than spreading them
out over the source.
Spread your code out more:
let sum a = let rec sum i a = if (i > 0) then a.(i) +. sum (i-1) a else if
(i = 0) then a.(i) else 0.
in sum ((Array.length a) - 1) a
let sum a =
let rec sum i a =
if i > 0 then a.(i) +. sum (i-1) a else
if i = 0 then a.(i) else 0. in
sum (Array.length a - 1) a
It looks like you might be creating several arrays that are only filled in at
the end, in which case it is probably better to create them at the end of a
calculating using something like Array.init.
Your code often has similar looking parts. You can probably factor out a lot
of common functionality into higher-order functions, reducing code size and
the number of mistakes at the cost of a little performance due to the
genericity of the resulting code.
Especially with long variable names, you may be able to shrink your code by
nesting more. For example, to avoid passing parameters across many function
calls. This can also conflict with performance but for more subtle reasons.
Use "&&" and "||" rather than "&" and "or".
You often write:
let x=1 in begin
for i=1 to 10 do
...
done
end
when you could write:
let x=1 in
for i=1 to 10 do
...
done
Reducing maxNumberOfIterations to 1, the final time given is 78.54s on my
900MHz 32-bit Athlon and 55.67s on my 800MHz AMD64.
You can shave 2% off the time by factoring the computation of pi from
randomGaussian. You can reduce the run-time by 25% by using a faster
randomGaussian function (e.g. the one given in NR) and compiling with
"-inline 100".
HTH.
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
Objective CAML for Scientists
http://www.ffconsultancy.com/products/ocaml_for_scientists
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-12-16 19:41 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-12-15 10:33 Comments welcomed to progr. style / speed of my first ocaml program "Error correcting LDPC decoder" Andries Hekstra
[not found] ` <OFB50A01B3.ECDA5A94-ONC12570D8.00394FEA-C12570D8.003A2427@philips.com >
2005-12-15 12:03 ` [Caml-list] " Gerd Stolpmann
2005-12-15 12:40 ` Gerd Stolpmann
2005-12-15 15:09 ` Xavier Leroy
2005-12-16 19:35 ` Jon Harrop
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox