ANNOUNCE: jhc 0.6.0 Haskell Compiler
Hi, I am pleased to announce jhc 0.6.0, It has been a long time since an official release, so there have been a lot of changes. Jhc is an optimizing haskell compiler that focuses on creating fast and portable code. Jhc is still mainly of interest to jhc hackers and developers than the general haskell public, but it is starting to see use in embedded development with haskell so I decided to make more public announcements of major releases in the future. some links: The jhc homepage: http://repetae.net/computer/jhc/ Installation Instructions: http://repetae.net/computer/jhc/building.shtml The jhc manual: http://repetae.net/computer/jhc/manual.html And I am happy to announce, there is now a yum repository* for jhc and my other projects (such as DrIFT), so if you use an rpm based linux distribution, you can keep up to date with jhc official releases by doing: ; rpm -i http://repetae.net/yum/repetae-repo-1.0-3.noarch.rpm ; yum install jhc A couple recent changes: jhc now comes bundled with the 'containers' and 'applicative' library making it much easier to compile many haskell programs out there. (Data.Graph, Data.IntMap, Data.IntSet, Data.Map, Data.Sequence, Data.Set, Data.Tree, Control.Applicative, Control.Arrow, Control.Category, Data.Foldable, Data.Traversable) signifigant speed and resource usage improvements in compilation time. transparent cross compilation support for creating windows programs on a unix box. (or iPhone/Nokia Tablet/etc..) If you are interested in jhc development, please sign up on the jhc mailing list here: http://www.haskell.org/mailman/listinfo/jhc John * I would love to get proper 'deb's and BSD packages built also automatically, if anyone wants to help with this, please join the list and let us know. -- John Meacham - ⑆repetae.net⑆john⑈
Hi, This compiler is very promising, for the least. Here is a small dummy Haskell program. countdown :: Int -> IO () countdown 0 = putStrLn "finished" countdown x = do putStrLn (show x) countdown (x-1) main = countdown 10000000 and the C program that comes to closest. #include <stdio.h> int main(void) { int i; for(i=0; i<10000000; i++) { printf("%d\n",i); } printf("finished\n"); return 0; } GHC is 6.10.1, gcc is 4.3.2, jhc is 0.6.0 arch is i386/Linux(Ubuntu) $ ghc hello.hs -o hello1 $ jhc hello.hs -o hello2 $ gcc hello.c -o hello3 What about the size of the executables? $ ls -l hello1 hello2 hello3 493567 hello1 16803 hello2 9083 hello3 let strip them. 309492 hello1 10092 hello2 5664 hello3 In the case of jhc, there is definitively room for some improvements. I dare not say what I think of ghc. Now, let run them. $ time ./hello1 > /dev/null real 0m12.092s user 0m12.005s sys 0m0.052s $ time ./hello2 > /dev/null real 0m2.016s user 0m1.016s sys 0m1.000s $ time ./hello3 > /dev/null real 0m2.609s user 0m2.588s sys 0m0.020s Actually, times varie between runs. It tends to decrease (except for the ghc generated binary), so I suppose it is due to OS cache effects. Yet, I consistently observed that, according to "time", hello2 (jhc) runs _faster_ than hello3 (gcc). Something is wrong: how can Haskell be faster than C? Last but not least, as well as generating fast code, jhc can make good use of a C cross-compiler as back-end. Well done. Sylvain Nahas
On 2009 Mar 18, at 19:16, sylvain wrote:
Actually, times varie between runs. It tends to decrease (except for the ghc generated binary), so I suppose it is due to OS cache effects. Yet, I consistently observed that, according to "time", hello2 (jhc) runs _faster_ than hello3 (gcc).
Something is wrong: how can Haskell be faster than C?
I suspect if you profile you'll find that Haskell's show is faster than C's printf, especially if the appropriate show instance is selected at compile time. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH
nice, although not quite fair, as jhc always has optimization turned on, so compiling the others with -O is more appropriate. The 'show' instance is clearly eating up most of the time in the jhc version, if you look at the generated C code. here is main as generated by jhc annotated with the haskell it cooresponds to in the comments : static void A_STD ftheMain(void) { // passing in 100000000 to countdown uint32_t v184744394 = 10000000; // countdown :: Int -> IO () fW_a__fMain__fl_aMain__countdown_d43_u8:; { sptr_t v261990436 = ((sptr_t)VALUE(v184744394)); // check if it is zero if (0 == v184744394) { // putStr "finished" fPrelude__IO__putStr(c8); // putChar '\n' return (void)jhc_utf8_putchar((int)10); } else { // let s = show x wptr_t v100000 = fInstance_a__iJhc__Show__show__default(v261990436); sptr_t v118875000 = demote(v100000); // putsStr s fPrelude__IO__putStr(v118875000); // putChar '\n' (void)jhc_utf8_putchar((int)10); // jump to countdown with x = x - 1 uint32_t v14532078 = (v184744394 - 1); v184744394 = v14532078; goto fW_a__fMain__fl_aMain__countdown_d43_u8; } } } John -- John Meacham - ⑆repetae.net⑆john⑈
so compiling the others with -O is more appropriate.
It seems the consensus is I should have activated optimizations. Let check that, same code in the same order (ghc, jhc, gcc). I changed only the options for ghc and gcc. Below is the Makefile, you can double check. with -O 0:09.96 real,9.86 user,0.06 sys 0:02.06 real,1.02 user,0.92 sys 0:02.80 real,2.55 user,0.00 sys with -O2 0:09.81 real,9.70 user,0.07 sys 0:01.95 real,1.01 user,0.93 sys 0:02.57 real,2.56 user,0.00 sys with -O3 0:09.86 real,9.78 user,0.06 sys 0:01.98 real,1.02 user,0.95 sys 0:02.63 real,2.64 user,0.00 sys I have tried with gcc 3.4 and 4.3.2. All results are consistent. Sylvain Nahas Makefile --------------------- OPT:=-O3 CC:=gcc-3.4 CFLAGS:=-Wall $(OPT) JHC:=/home/sylvain/bin/jhc-0.6.0/bin/jhc GHCFLAGS:=$(OPT) TIMEFMT:=-f "%E real,%U user,%S sys" all: test1 test2 test3 .PHONY: test1 test2 test3 test1: hello1 time $(TIMEFMT) ./$^ >/dev/null test2: hello2 time $(TIMEFMT) ./$^ >/dev/null test3: hello3 time $(TIMEFMT) ./$^ >/dev/null hello1: hello.hs ghc $(GHCFLAGS) $^ -o $@ hello2: hello.hs $(JHC) $^ -o $@ hello3: hello.c $(CC) $(CFLAGS) $^ -o $@ clean: -rm hello1 hello2 hello3 hello.hi hello.ho hello_code
sylvain.nahas:
Hi,
This compiler is very promising, for the least.
Here is a small dummy Haskell program. countdown :: Int -> IO () countdown 0 = putStrLn "finished" countdown x = do putStrLn (show x) countdown (x-1) main = countdown 10000000
and the C program that comes to closest. #include <stdio.h> int main(void) { int i; for(i=0; i<10000000; i++) { printf("%d\n",i); } printf("finished\n"); return 0; }
GHC is 6.10.1, gcc is 4.3.2, jhc is 0.6.0 arch is i386/Linux(Ubuntu)
$ ghc hello.hs -o hello1 $ jhc hello.hs -o hello2 $ gcc hello.c -o hello3
Oh boy. Compile with optimizations on please! ghc -O2 et al.
Le samedi 21 mars 2009 à 09:58 -0700, Don Stewart a écrit :
Oh boy. Compile with optimizations on please! ghc -O2 et al.
Hi. I had done that, actually, before even my first post, and knew that it changes little to the picture, at least on my system. Please check the other post, where I publish the results with optimization turned on. http://www.haskell.org/pipermail/jhc/2009-March/000311.html I have also tested with another program, from the "Great Computer Language Shootout". http://www.haskell.org/pipermail/jhc/2009-March/000313.html Sylvain Nahas
sylvain <sylvain.nahas@googlemail.com> writes:
Le samedi 21 mars 2009 à 09:58 -0700, Don Stewart a écrit :
Oh boy. Compile with optimizations on please! ghc -O2 et al.
I had done that, actually, before even my first post, and knew that it changes little to the picture, at least on my system.
I think Bulat was right on the money here: you're essentially testing the efficiency of writing integers. Presumably, JHC is better than GHC at specializing/inlining this library function. -k -- If I haven't seen further, it is by standing in the footprints of giants
On Mon, Mar 23, 2009 at 08:40:02AM +0100, Ketil Malde wrote:
I had done that, actually, before even my first post, and knew that it changes little to the picture, at least on my system.
I think Bulat was right on the money here: you're essentially testing the efficiency of writing integers. Presumably, JHC is better than GHC at specializing/inlining this library function.
Indeed, but isn't being better at specializing/inlining exactly what an optimizing compiler should do. :) In any case, these results are not atypical, generally, if jhc can compile something, it ends up being 2-3x faster than ghc. After all, C-comparable (or even superior) speed is the main goal of jhc development. And if anything, I am more convinced than when I started that the goal is achievable. With jhc today, C comparable performance from numerical code is not difficult to achieve with some attention to strictness annotations. John -- John Meacham - ⑆repetae.net⑆john⑈
Those are impressive results. Typically on programming language benchmarks, the speed of ghc-generated code fares well against C, sometimes outperforming it, at best being 20x faster, at worst being 3x slower. Since it already seems "fast enough", I'm astonished that jhc could make it even faster. http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&lang=ghc&lang2... Where ghc-generated code fares poorly against other languages is memory usage. Has there been an effort in jhc to reduce the memory footprint of generated code? How does it fare against ghc in this area? Thanks, Lyle On Mon, Mar 23, 2009 at 1:09 AM, John Meacham <john@repetae.net> wrote:
On Mon, Mar 23, 2009 at 08:40:02AM +0100, Ketil Malde wrote:
I had done that, actually, before even my first post, and knew that it changes little to the picture, at least on my system.
I think Bulat was right on the money here: you're essentially testing the efficiency of writing integers. Presumably, JHC is better than GHC at specializing/inlining this library function.
Indeed, but isn't being better at specializing/inlining exactly what an optimizing compiler should do. :)
In any case, these results are not atypical, generally, if jhc can compile something, it ends up being 2-3x faster than ghc. After all, C-comparable (or even superior) speed is the main goal of jhc development. And if anything, I am more convinced than when I started that the goal is achievable. With jhc today, C comparable performance from numerical code is not difficult to achieve with some attention to strictness annotations.
John
-- John Meacham - ⑆repetae.net⑆john⑈ _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Hi, your post gave me the idea to profile the memory usage of the generated binary with valgrind.
Has there been an effort in jhc to reduce the memory footprint of generated code?
In this release of jhc, the problem is handled in a quite radical way. It seems that no free() is ever emitted, the allocated heap memory is not released. Well, this classifies like a bug, I guess. On the bright side, when I removed all memory deallocation from the C version, supposing (naively maybe) that it would radicaly reduce the difference in performance, jhc's still ran twice faster. Sylvain Nahas
The last version still uses a region inference algoritm instead of a garbage collector?. 2009/3/17 John Meacham <john@repetae.net>
Hi, I am pleased to announce jhc 0.6.0, It has been a long time since an official release, so there have been a lot of changes. Jhc is an optimizing haskell compiler that focuses on creating fast and portable code. Jhc is still mainly of interest to jhc hackers and developers than the general haskell public, but it is starting to see use in embedded development with haskell so I decided to make more public announcements of major releases in the future.
some links:
The jhc homepage: http://repetae.net/computer/jhc/
Installation Instructions: http://repetae.net/computer/jhc/building.shtml
The jhc manual: http://repetae.net/computer/jhc/manual.html
And I am happy to announce, there is now a yum repository* for jhc and my other projects (such as DrIFT), so if you use an rpm based linux distribution, you can keep up to date with jhc official releases by doing:
; rpm -i http://repetae.net/yum/repetae-repo-1.0-3.noarch.rpm ; yum install jhc
A couple recent changes:
jhc now comes bundled with the 'containers' and 'applicative' library making it much easier to compile many haskell programs out there. (Data.Graph, Data.IntMap, Data.IntSet, Data.Map, Data.Sequence, Data.Set, Data.Tree, Control.Applicative, Control.Arrow, Control.Category, Data.Foldable, Data.Traversable)
signifigant speed and resource usage improvements in compilation time.
transparent cross compilation support for creating windows programs on a unix box. (or iPhone/Nokia Tablet/etc..)
If you are interested in jhc development, please sign up on the jhc mailing list here: http://www.haskell.org/mailman/listinfo/jhc
John
* I would love to get proper 'deb's and BSD packages built also automatically, if anyone wants to help with this, please join the list and let us know.
-- John Meacham - ⑆repetae.net⑆john⑈ _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
On Thu, Mar 19, 2009 at 03:22:33PM +0100, Alberto G. Corona wrote:
The last version still uses a region inference algoritm instead of a garbage collector?.
It turns out the choice of garbage collector is fairly independent of the rest of the compiler, so there is a flag to decide on what garbage collector to use (or none). Right now, however, there isn't really a universally good choice, the boehm gc will work, but it is quite slow. I am working on a middle of the road solution between full static analysis and garbage collection based on the mercury garbage collector for compilation to C, but of course, when compiling to something like llvm or C--, a different garbage collector might be in order. So, It is likely jhc will have multiple choices when it comes to garbage collection for a while until an obviously correct answer emerges. In the meantime, improving the static analysis (such as full region inference will do) helps all back ends so I will likely spend some time focusing on that. John -- John Meacham - ⑆repetae.net⑆john⑈
john:
Hi, I am pleased to announce jhc 0.6.0, It has been a long time since an official release, so there have been a lot of changes. Jhc is an optimizing haskell compiler that focuses on creating fast and portable code. Jhc is still mainly of interest to jhc hackers and developers than the general haskell public, but it is starting to see use in embedded development with haskell so I decided to make more public announcements of major releases in the future.
Hey John, I get the following build error: /usr/bin/ghc -fbang-patterns -O -ignore-package lang -W -fno-warn-unused-matches -fwarn-type-defaults -i -i./drift_processed -i./. -i. -odir . -hidir . -package mtl -package unix -ignore-package lang -package utf8-string -package binary -package zlib -fallow-undecidable-instances -fglasgow-exts -fallow-overlapping-instances --make Main.hs StringTable/StringTable_cbits.o cbits/md5sum.o -o jhc on the commandline: Warning: -fbang-patterns is deprecated: use -XBangPatterns or pragma {-# LANGUAGE BangPatterns#-} instead on the commandline: Warning: -fallow-undecidable-instances is deprecated: use -XUndecidableInstances or pragma {-# LANGUAGE UndecidableInstances#-} instead on the commandline: Warning: -fallow-overlapping-instances is deprecated: use -XOverlappingInstances or pragma {-# LANGUAGE OverlappingInstances#-} instead Util/Gen.hs:6:7: Could not find module `Control.Monad.Identity': it was found in multiple packages: transformers-0.1.1.0 mtl-1.1.0.2 make[1]: *** [jhc] Error 1 I *think* you have to -hide-all-packages then enable the ones you want one-by-one (check whatever commandline cabal emits here). Cheers, Don
On Sat, Mar 21, 2009 at 10:00:33AM -0700, Don Stewart wrote:
john:
Hi, I am pleased to announce jhc 0.6.0, It has been a long time since an official release, so there have been a lot of changes. Jhc is an optimizing haskell compiler that focuses on creating fast and portable code. Jhc is still mainly of interest to jhc hackers and developers than the general haskell public, but it is starting to see use in embedded development with haskell so I decided to make more public announcements of major releases in the future.
Hey John,
I get the following build error:
/usr/bin/ghc -fbang-patterns -O -ignore-package lang -W -fno-warn-unused-matches -fwarn-type-defaults -i -i./drift_processed -i./. -i. -odir . -hidir . -package mtl -package unix -ignore-package lang -package utf8-string -package binary -package zlib -fallow-undecidable-instances -fglasgow-exts -fallow-overlapping-instances --make Main.hs StringTable/StringTable_cbits.o cbits/md5sum.o -o jhc
on the commandline: Warning: -fbang-patterns is deprecated: use -XBangPatterns or pragma {-# LANGUAGE BangPatterns#-} instead
on the commandline: Warning: -fallow-undecidable-instances is deprecated: use -XUndecidableInstances or pragma {-# LANGUAGE UndecidableInstances#-} instead
on the commandline: Warning: -fallow-overlapping-instances is deprecated: use -XOverlappingInstances or pragma {-# LANGUAGE OverlappingInstances#-} instead
Util/Gen.hs:6:7: Could not find module `Control.Monad.Identity': it was found in multiple packages: transformers-0.1.1.0 mtl-1.1.0.2 make[1]: *** [jhc] Error 1
I *think* you have to -hide-all-packages then enable the ones you want one-by-one (check whatever commandline cabal emits here).
Hmm... what version of ghc are you using? I tested against ghc 6.8 since that is all I have available on my machines so it is possible the bugs are because you are using ghc 6.10. If the -hide-all-packages trick works for 6.8 too then I will do that always. I dropped 6.6 compatability at some point, but want to keep 6.8 in addition to 6.10 since that is among other things what amazon ec2 instances come with (since they are based on fedora core 8). Man. those high CPU ec2 instances are great for plowing through regression tests. :) John -- John Meacham - ⑆repetae.net⑆john⑈
On Sat, Mar 21, 2009 at 10:00 AM, Don Stewart <dons@galois.com> wrote:
Util/Gen.hs:6:7: Could not find module `Control.Monad.Identity': it was found in multiple packages: transformers-0.1.1.0 mtl-1.1.0.2 make[1]: *** [jhc] Error 1
ghc-pkg hide transformers-0.1.1.0 -- Taral <taralx@gmail.com> "Please let me know if there's any further trouble I can give you." -- Unknown
participants (9)
-
Alberto G. Corona -
Bas van Dijk -
Brandon S. Allbery KF8NH -
Don Stewart -
John Meacham -
Ketil Malde -
Lyle Kopnicky -
sylvain -
Taral