https://wiki.haskell.org/api.php?action=feedcontributions&user=Barubary&feedformat=atomHaskellWiki - User contributions [en]2022-01-16T23:22:37ZUser contributionsMediaWiki 1.27.4https://wiki.haskell.org/index.php?title=Playing_by_the_rules&diff=16719Playing by the rules2007-11-08T15:40:44Z<p>Barubary: </p>
<hr />
<div>GHC's [http://haskell.org/haskellwiki/GHC/Using_rules term rewriting engine] provides a playground for all sorts of user-defined optimisations and<br />
tweaks to Haskell code. This page collects examples of the use of<br />
rewrite rules. There is more information available on the GHC [http://hackage.haskell.org/trac/ghc/wiki/RewriteRules rewrite rules] page.<br />
<br />
== reverse . reverse = id ==<br />
<br />
The following question was asked in [[IRC channel|#haskell]]:<br />
<br />
15:40 Excedrin> why doesn't 'head $ reverse $ reverse [1..]' work in Haskell?<br />
<br />
The answer is: it does work, if you tell the compiler that:<br />
<br />
<haskell><br />
reverse . reverse = id<br />
</haskell><br />
<br />
Using the following rewrite rule:<br />
<br />
<haskell><br />
{-# RULES<br />
"reverse.reverse/id" reverse . reverse = id<br />
#-}<br />
<br />
main = print . head . reverse . reverse $ [1..]<br />
</haskell><br />
<br />
We can "optimise" this program, changing a non-terminating program:<br />
<haskell><br />
$ ./a.out<br />
^C<br />
</haskell><br />
<br />
into a much faster one:<br />
<br />
<haskell><br />
$ ghc -fglasgow-exts -ddump-simpl-stats A.hs<br />
5 PostInlineUnconditionally<br />
4 UnfoldingDone<br />
1 RuleFired<br />
1 reverse.reverse/id<br />
7 BetaReduction<br />
3 SimplifierDone<br />
<br />
$ ./a.out<br />
1<br />
</haskell><br />
<br />
As can be seen here, rewrite rules let you teach the compiler about<br />
interesting algebraic properties you code satisfies, that it can't find<br />
on its own.<br />
<br />
'''Note:''' In general it's a bad idea for rules to change the semantics (meaning) of your code in such a way. Consider someone using <tt>reverse . reverse</tt> to demand strictness of an IO action, this code would no longer work with the above rule.<br />
<br />
== Fast ByteString construction ==<br />
<br />
Another technique is to use rewrite rules to remove intermediate lists<br />
when building bytestrings from literal string constants. The problem is<br />
that string constants must be converted from a [Char] to a ByteString,<br />
to use literal strings as ByteStrings. This is highly inefficient, when<br />
GHC already allocates string constants as unboxed byte arrays. We can<br />
bypass the [Char] conversion using rewrite rules.<br />
<br />
Supposing we want to use a ByteString literal:<br />
<br />
<haskell><br />
import qualified Data.ByteString.Char8 as C<br />
<br />
mystring = C.pack "rewrite rules are fun!"<br />
main = C.putStrLn mystring<br />
</haskell><br />
<br />
and it is compiled by GHC to:<br />
<br />
<haskell><br />
mystring_rDR = Data.ByteString.Char8.pack (GHC.Base.unpackCString# "rewrite rules are fun!"#)<br />
<br />
Main.main = Data.ByteString.putStrLn mystring_rDR<br />
<br />
:Main.main = GHC.TopHandler.runMainIO @ () Main.main<br />
</haskell><br />
<br />
Now, the string literal has been packed by GHC for us into a Addr#, pointing<br />
to a proper C string. Now, we'd like to remove that intermediate<br />
unpackCString#, and just pack the string literal straight into a ByteString,<br />
avoiding an intermediate list.<br />
<br />
So we add a rewrite rule:<br />
<br />
<haskell><br />
{-# RULES<br />
"pack/packAddress" forall s . pack (unpackCString# s) = B.packAddress s<br />
#-}<br />
</haskell><br />
<br />
Now, when compiled with -O -fglasgow-exts, we get:<br />
<br />
<haskell><br />
1 RuleFired<br />
1 FPS pack/packAddress<br />
</haskell><br />
<br />
and the code is transformed as follows:<br />
<br />
<haskell><br />
mystring = Data.ByteString.Base.packAddress "rewrite rules are fun!"<br />
</haskell><br />
<br />
to<br />
<br />
<haskell><br />
mystring = Data.ByteString.Char8.pack (GHC.Base.unpackCString# "rewrite rules are fun<br />
</haskell><br />
<br />
and then the rewrite rule kicks in, and we construct a new ByteString directly<br />
from the Addr#, via a call to strlen to get the length:<br />
<br />
<haskell><br />
mystring =<br />
let addr#_a146 :: GHC.Prim.Addr#<br />
addr#_a146 = "rewrite rules are fun!"#<br />
in case Data.ByteString.Base.$wccall addr#_a146 s2#_a1Q8 of<br />
(# ds3_a1Re, ds4_a1Rf #) -><br />
Data.ByteString.Base.PS addr#_a146<br />
(GHC.ForeignPtr.PlainForeignPtr var#_a1Q9)<br />
0<br />
(GHC.Prim.word2Int# ds4_a1Rf)<br />
</haskell><br />
<br />
''exactly'' what we'd like. So at runtime, this string will require only a call<br />
to strlen to build.<br />
<br />
== Locating errors ==<br />
<br />
Rewrite rules can ''almost'' be used to solve the infamous 'fromJust: Nothing'<br />
error message. Couldn't we just use rewrite rules to rewrite ''*transparently''<br />
all uses of fromJust to safeFromJust, tagging the call site with a location?<br />
To work this requires a few things to go right:<br />
<br />
* a rewrite rule<br />
* assertions<br />
* and rewrite rules firing before assertions are expanded<br />
<br />
Let's try this. Consider the program:<br />
<br />
<haskell><br />
1 import qualified Data.Map as M<br />
2 import Data.Maybe<br />
3<br />
4 main = print f<br />
5<br />
6 f = let m = M.fromList<br />
7 [(1,"1")<br />
8 ,(2,"2")<br />
9 ,(3,"3")]<br />
10 s = M.lookup 4 m<br />
11 in fromJust s<br />
</haskell><br />
<br />
When we run it we get the not so useful error:<br />
<br />
$ ./A<br />
A: Maybe.fromJust: Nothing<br />
<br />
Ok, so we have a few tricks for locating this, using<br />
[http://www.cse.unsw.edu.au/~dons/loch.html LocH], we can catch an assertion<br />
failure, but we have to insert the assertion by hand:<br />
<br />
<haskell><br />
1 import Debug.Trace.Location<br />
2 import qualified Data.Map as M<br />
3 import Data.Maybe<br />
4<br />
5 main = do print f<br />
6<br />
7 f = let m = M.fromList<br />
8 [(1,"1")<br />
9 ,(2,"2")<br />
10 ,(3,"3")]<br />
11 s = M.lookup 4 m<br />
12 in safeFromJust assert s<br />
13<br />
14 safeFromJust a = check a . fromJust<br />
</haskell><br />
<br />
Which correctly identifies the call site:<br />
<br />
$ ./A<br />
A: A.hs:12:20-25: Maybe.fromJust: Nothing<br />
<br />
Now, this approach is a little fragile. 'assert' is only respected by GHC if -O<br />
is ''not'' on, so if we happened to try this trick with -O, we'd get:<br />
<br />
$ ./A<br />
A: Debug.Trace.Location.failure<br />
<br />
So lesson one: you have to do the bug hunting with -Onot.<br />
<br />
Currently there's -fignore-asserts for turning off assertions, but no flag for<br />
turning them on with -O, Simon, could this be fixed? Could we get a<br />
-frespect-asserts that works even with -O ?<br />
<br />
Ok, assuming this assert trick is used, can we get the compiler to insert the<br />
asserts for us? If so, this would be a great advantage, you'd just be able to<br />
switch on a flag, or import a debugging module, and your fromJusts would be<br />
transparently rewritten. With rewrite rules we do just this!<br />
<br />
So, to our initial unsafe use of fromJust, we add a rewrite rule:<br />
<br />
<haskell><br />
--<br />
-- rewrite fromJust to a located version, and hope that GHC expands<br />
-- 'assert' after the rule fires..<br />
--<br />
{-# RULES<br />
"located fromJust" fromJust = check assert . myFromJust<br />
#-}<br />
</haskell><br />
<br />
This just tells the compiler to replace every occurence of fromJust with a<br />
assertion-throwing fromJust, should it fail. We have to use myFromJust here, to<br />
avoid rule recursion.<br />
<br />
<haskell><br />
--<br />
-- Inlined to avoid recursion in the rule:<br />
--<br />
myFromJust :: Maybe a -> a<br />
myFromJust Nothing = error "Maybe.fromJust: Nothing" -- yuck<br />
myFromJust (Just x) = x<br />
</haskell><br />
<br />
Ok, so can we get ghc to rewrite fromJust to the safe fromJust magicaly?<br />
<br />
$ ghc --make -Onot A.hs -fglasgow-exts -ddump-simpl-stats<br />
[1 of 1] Compiling Main ( A.hs, A.o )<br />
1 RuleFired<br />
1 located fromJust<br />
Linking A ...<br />
<br />
Yes, the rule fired! GHC *did* rewrite our fromJust to a more useful fromJust.<br />
Running it:<br />
<br />
<haskell><br />
$ ./A<br />
A: A.hs:19:36-41: Maybe.fromJust: Nothing<br />
</haskell><br />
<br />
Looks good! But that is deceiving: the assert was expanded before the rule<br />
fired, and refers to the rewrite rule source line (line 19), not the fromJust<br />
call site (line 12). Now if we could just have the 'assert' token inserted<br />
into the AST before it was expanded, we'd be home and dry. Could this be done<br />
with TH? Or could we arrange for asserts in rewrite rules not to be expanded<br />
till later?<br />
<br />
Note that this is still a useful technique, we can rewrite head/fromJust/... to<br />
some other possibly more useful message. And if we can constrain the rule to fire<br />
in only particular modules, we may be able to narrow down the bug, just by<br />
turning on a rule. For example, adding:<br />
<br />
<haskell><br />
{-# RULES<br />
"located fromJust" fromJust = safeFromJust<br />
#-}<br />
<br />
safeFromJust s = case s of<br />
Nothing -> "safeFromJust: failed with Nothing. Ouch"<br />
Just x -> x<br />
</haskell><br />
<br />
will produce:<br />
<br />
<haskell><br />
$ ./A<br />
"safeFromJust: failed with Nothing. Ouch"<br />
</haskell><br />
<br />
So rewrite rules can be used to transparently alter uses of partial functions<br />
like head and fromJust.<br />
<br />
== Fusion and deforestation ==<br />
<br />
By far the most elaborate use of compiler rewrite rules is to perform<br />
automatic deforestation of intermediate data structures. This is<br />
documented in a number of [[Research_papers/Compilation#Fusion_and_deforestation|research papers]].<br />
Note that also for this application field of rewrite rules the above mentioned problem of potentially changing the semantics of programs occurs. Read further under [[Correctness of short cut fusion|correctness of short cut fusion]].<br />
<br />
== Symbolic differentiation ==<br />
<br />
I like to demonstrate to people, that GHC has already built-in a kind of Computer Algebra system.<br />
The optimizer can be abused to differentiate expressions symbolically.<br />
Unfortunately it cannot be forced to do so.<br />
That's why, some, better say: too many, expressions are not derived.<br />
<br />
* http://www.haskell.org/pipermail/haskell-cafe/2005-March/009489.html<br />
* http://darcs.haskell.org/htam/src/ExploreHaskell/SymbolicDifferentiation.hs<br />
<br />
<br />
[[Category:Tutorials]]<br />
[[Category:Mathematics]]<br />
[[Category:Performance]]</div>Barubaryhttps://wiki.haskell.org/index.php?title=Performance/GHC&diff=16718Performance/GHC2007-11-08T14:55:16Z<p>Barubary: </p>
<hr />
<div>{{Performance infobox}}<br />
[[Category:Performance|GHC]] [[Category:GHC]]<br />
Please report any overly-slow GHC-compiled programs. Since [[GHC]] doesn't have any credible competition in the performance department these days it's hard to say what overly-slow means, so just use your judgement! Of course, if a GHC compiled program runs slower than the same program compiled with another Haskell compiler, then it's definitely a bug. Furthermore, if an equivalent OCaml, SML or Clean program is faster, this ''might'' be a bug.<br />
<br />
== Use optimisation ==<br />
<br />
Optimise, using <tt>-O</tt> or <tt>-O2</tt>: this is the most basic way to make your program go faster. Compilation time will be slower, especially with <tt>-O2</tt>.<br />
<br />
At present, <tt>-O2</tt> is nearly indistinguishable from <tt>-O</tt>.<br />
<br />
GHCi cannot optimise interpreted code, so when using GHCi, compile critical modules using <tt>-O</tt> or <tt>-O2</tt>, then load them into GHCi.<br />
<br />
Here is a short summary of useful compile time flags:<br />
* <tt>-O</tt>:<br />
* <tt>-O2</tt>:<br />
* Do NOT use <tt>-O3</tt>, it actually gives less optimization than <tt>-O2</tt>, [[http://hackage.haskell.org/trac/ghc/ticket/1261]]<br />
* <tt>-funfolding-use-threshold=16</tt>: demand more inlining.<br />
* <tt>-fexcess-precision</tt>: see [[Performance/Floating_point]]<br />
* <tt>-optc-O3</tt>: Enables a suite of optimizations in the GCC compiler. See the [http://www.openbsd.org/cgi-bin/man.cgi?query=gcc&sektion=1 gcc(1) man-page] for details. (a C-compiler option).<br />
* <tt>-optc-ffast-math</tt>: A C-compiler option which allows it to be less strict with respect to the standard when compiling IEEE 754 floating point arithmetic. Math operations will not trap if something goes wrong and math operations will assume that NaN and +- Infinity are not in arguments or results. For most practical floating point processing, this is a non-issue and enabling the flag can speed up FP arithmetic by a considerable amount. Also see the gcc(1) man-page. (a C-compiler option).<br />
<br />
Other useful flags:<br />
* <tt>-ddump-simpl > core.txt</tt>: generate core.txt file (see below).<br />
<br />
<br />
== Measuring performance ==<br />
<br />
The first thing to do is measure the performance of your program, and find out whether all the time is being spent in the garbage collector or not. Run your program with the <tt>+RTS -sstderr</tt> option:<br />
<br />
$ ./clausify 20 +RTS -sstderr<br />
42,764,972 bytes allocated in the heap<br />
6,915,348 bytes copied during GC (scavenged)<br />
360,448 bytes copied during GC (not scavenged)<br />
36,616 bytes maximum residency (7 sample(s))<br />
<br />
81 collections in generation 0 ( 0.07s)<br />
7 collections in generation 1 ( 0.00s)<br />
<br />
2 Mb total memory in use<br />
<br />
INIT time 0.00s ( 0.00s elapsed)<br />
MUT time 0.65s ( 0.94s elapsed)<br />
GC time 0.07s ( 0.06s elapsed)<br />
EXIT time 0.00s ( 0.00s elapsed)<br />
Total time 0.72s ( 1.00s elapsed)<br />
<br />
%GC time 9.7% (6.0% elapsed)<br />
<br />
Alloc rate 65,792,264 bytes per MUT second<br />
<br />
Productivity 90.3% of total user, 65.1% of total elapsed<br />
<br />
This tells you how much time is being spent running the program itself (MUT time), and how much time spent in the garbage collector (GC time). <br />
<br />
If your program is doing a lot of GC, then your first priority should be to check for [[Performance:Space Leaks|Space Leaks]] using [http://www.haskell.org/ghc/docs/latest/html/users_guide/prof-heap.html heap profiling], and then to try to reduce allocations by [http://www.haskell.org/ghc/docs/latest/html/users_guide/prof-time-options.html time and allocation profiling]. <br />
<br />
If you can't reduce the GC cost any further, then using more memory by tweaking the [http://www.haskell.org/ghc/docs/latest/html/users_guide/runtime-control.html#rts-options-gc GC options] will probably help. For example, increasing the default heap size with <tt>+RTS -H128m</tt> will reduce the number of GCs.<br />
<br />
If your program isn't doing too much GC, then you should proceed to [http://www.haskell.org/ghc/docs/latest/html/users_guide/prof-time-options.html time and allocation profiling] to see where the big hitters are.<br />
<br />
== Unboxed types ==<br />
<br />
When you are ''really'' desperate for speed, and you want to get right down to the &ldquo;raw bits.&rdquo; Please see [http://www.haskell.org/ghc/docs/latest/html/users_guide/primitives.html GHC Primitives] for some information about using unboxed types.<br />
<br />
This should be a last resort, however, since unboxed types and primitives are non-portable. Fortunately, it is usually not necessary to resort to using explicit unboxed types and primitives, because GHC's optimiser can do the work for you by inlining operations it knows about, and unboxing strict function arguments (see [[Performance/Strictness]]). Strict and unpacked constructor fields can also help a lot (see [[Performance/Data Types]]). Sometimes GHC needs a little help to generate the right code, so you might have to look at the Core output to see whether your tweaks are actually having the desired effect.<br />
<br />
One thing that can be said for using unboxed types and primitives is that you ''know'' you're writing efficient code, rather than relying on GHC's optimiser to do the right thing, and being at the mercy of changes in GHC's optimiser down the line. This may well be important to you, in which case go for it.<br />
<br />
=== An example ===<br />
<br />
Usually unboxing is not explicitly required (see the Core tutorial below), however there<br />
are circumstances where you require precise control over how your code is<br />
unboxed. The following program was at one point an entry in the<br />
[http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=ghc&lang2=ghc Great Language Shootout]. <br />
GHC did a good job unboxing the loop, but wouldn't generate the best loop. The<br />
solution was to unbox the loop function by hand, resulting in better code.<br />
<br />
The original code:<br />
<br />
loop :: Int -> Double -> Double<br />
loop d s = if d == 0 then s<br />
else loop (d-1) (s + 1/fromIntegral d)<br />
The hand-unboxed code (note that it is uglier, and harder to read):<br />
<br />
import GHC.Base<br />
import GHC.Float<br />
<br />
loop :: Int# -> Double# -> Double#<br />
loop d s = if d ==# 0# then s <br />
else loop (d -# 1#) (s +## (1.0## /## int2Double# d))<br />
<br />
GHC 6.4.1 compiles the first loop to:<br />
<br />
$wloop :: Int# -> Double# -> Double#<br />
$wloop = \ (ww_s2Ga :: Int#) (ww1_s2Ge :: Double#) -><br />
case Double# ww_s2Ga of wild_XC {<br />
__DEFAULT -><br />
case /## 1.0 (int2Double# wild_XC) of y_a2Cd { <br />
__DEFAULT -> $wloop (-# wild_XC 1) (+## ww1_s2Ge y_a2Cd)<br />
};<br />
0 -> ww1_s2Ge<br />
}<br />
<br />
And the second, unboxed loop is translated to<br />
<br />
loop1 :: Int# -> Double# -> Double#<br />
loop1 = \ (d_a1as :: Int#) (s_a1at :: Double#) -><br />
case Double# d_a1as of wild_B1 {<br />
__DEFAULT -> loop1 (-# wild_B1 1) (+## s_a1at (/## 1.0 (int2Double# wild_B1)));<br />
0 -> s_a1at<br />
}<br />
<br />
which contains 1 less case statement. The second version runs as fast as C, the<br />
first a bit slower. A similar problem was also solved with explicit unboxing in the [http://shootout.alioth.debian.org/gp4/benchmark.php?test=recursive&lang=all recursive benchmark entry].<br />
<br />
== Primops ==<br />
<br />
If you really, really need the speed, and other techniques don't seem to<br />
be helping, programming your code in raw GHC primops can sometimes do<br />
the job. As for unboxed types, you get some guarantees that your code's<br />
performance isn't subject to changes to the GHC optimisations, at the<br />
cost of more unreadable code.<br />
<br />
For example, in an imperative benchmark program a bottleneck was<br />
swapping two values. Raw primops solved the problem:<br />
<br />
swap i j a s =<br />
if i <# j then case readIntOffAddr# a i s of { (# s, x #) -><br />
case readIntOffAddr# a j s of { (# s, y #) -><br />
case writeIntOffAddr# a j x s of { s -><br />
case writeIntOffAddr# a i y s of { s -><br />
swap (i +# 1#) (j -# 1#) a s<br />
}}}}<br />
else (# s, () #)<br />
{-# INLINE swap #-}<br />
<br />
== Inlining ==<br />
<br />
GHC does a lot of inlining, which has a dramatic effect on performance.<br />
<br />
Without -O, GHC does inlining ''within'' a module, but no ''cross-module'' inlining. <br />
<br />
With -O, it does a lot of cross-module inlining. Indeed, generally<br />
speaking GHC will inline ''across'' modules just as much as it does<br />
''within'' modules, with a single large exception. If GHC sees that a<br />
function 'f' is called just once, it inlines it regardless of how big<br />
'f' is. But once 'f' is exported, GHC can never see that it's called<br />
exactly once, even if that later turns out to be the case. This<br />
inline-once optimisation is pretty important in practice. <br />
<br />
So: if you care about performance, do not export functions that are not used outside the module (i.e. use an explicit export list, and keep it as small as possible).<br />
<br />
Sometimes ''explicitly'' inlining critical chunks of code can help.<br />
The INLINE pragma can be used for this purpose; but not for recursive functions, since inlining them forever would obviously be a bad idea.<br />
<br />
If a function you want inlined contains a slow path, it can help a<br />
good deal to seperate the slow path into its own function and NOINLINE<br />
it. <br />
<br />
== Looking at the Core ==<br />
<br />
GHC's compiler intermediate language can be very useful for improving<br />
the performance of your code. Core is a functional language much like a very<br />
stripped down Haskell (by design), so it's still readable, and still purely<br />
functional. The general technique is to iteratively inspect how the critical<br />
functions of your program are compiled to Core, checking that they're compiled<br />
in the most optimal manner. Sometimes GHC doesn't quite manage to unbox your<br />
function arguments, float out common subexpressions, or unfold loops ideally --<br />
but you'll only know if you read the Core.<br />
<br />
References:<br />
* [http://haskell.org/ghc/docs/papers/core.ps.gz An External Representation for the GHC Core Language], Andrew Tolmach<br />
* [http://research.microsoft.com/Users/simonpj/Papers/comp-by-trans-scp.ps.gz A transformation-based optimiser for Haskell], Simon L. Peyton Jones and Andre Santos<br />
* [http://research.microsoft.com/Users/simonpj/Papers/inlining/index.htm Secrets of the Glasgow Haskell Compiler Inliner], Simon L. Peyton Jones and Simon Marlow<br />
* [http://research.microsoft.com/users/simonpj/papers/spineless-tagless-gmachine.ps.gz Implementing lazy functional languages on stock hardware: the Spineless Tagless G-machine], Simon L. Peyton Jones<br />
<br />
== Core by example ==<br />
<br />
Here's a step-by-step guide to optimising a particular program, <br />
the [http://shootout.alioth.debian.org/gp4/benchmark.php?test=partialsums&lang=ghc&id=2 partial-sums problem] from the [http://shootout.alioth.debian.org Great Language Shootout]. We developed a number<br />
of examples on [http://haskell.org/haskellwiki/Shootout/Partial_sums Haskell shootout entry] page.<br />
<br />
Begin with the naive translation of the Clean entry (which was fairly quick):<br />
Lots of math in a tight loop.<br />
<br />
import System<br />
import Numeric<br />
<br />
main = do n <- getArgs = readIO . head<br />
let sums = loop 1 n 1 0 0 0 0 0 0 0 0 0<br />
fn (s,t) = putStrLn $ (showFFloat (Just 9) s []) ++ "\t" ++ t<br />
mapM_ (fn :: (Double, String) - IO ()) (zip sums names)<br />
<br />
names = ["(2/3)^k", "k^-0.5", "1/k(k+1)", "Flint Hills", "Cookson Hills"<br />
, "Harmonic", "Riemann Zeta", "Alternating Harmonic", "Gregory"]<br />
<br />
loop k n alt a1 a2 a3 a4 a5 a6 a7 a8 a9<br />
| k n = [ a1, a2, a3, a4, a5, a6, a7, a8, a9 ]<br />
| otherwise = loop (k+1) n (-alt)<br />
(a1 + (2/3) ** (k-1))<br />
(a2 + k ** (-0.5))<br />
(a3 + 1 / (k * (k + 1)))<br />
(a4 + 1 / (k*k*k * sin k * sin k))<br />
(a5 + 1 / (k*k*k * cos k * cos k))<br />
(a6 + 1 / k)<br />
(a7 + 1 / (k*k))<br />
(a8 + alt / k)<br />
(a9 + alt / (2 * k - 1))<br />
<br />
Compiled with '''-O2''' it runs. However, the performance is ''really'' bad.<br />
Somewhere greater than 128M heap -- in fact eventually running out of<br />
memory. A classic space leak. So look at the generated Core. <br />
<br />
=== Inspect the Core ===<br />
<br />
The best way to check the Core that GHC generates is with the<br />
'''-ddump-simpl''' flag (dump the results after code simplification, and<br />
after all optimisations are run). The result can be verbose, so pipe it into a pager.<br />
<br />
Looking for the 'loop', we find that it has been compiled to a function with<br />
the following type:<br />
<br />
$sloop_r2U6 :: GHC.Prim.Double#<br />
-> GHC.Float.Double<br />
-> GHC.Float.Double<br />
-> GHC.Float.Double<br />
-> GHC.Float.Double<br />
-> GHC.Float.Double<br />
-> GHC.Float.Double<br />
-> GHC.Float.Double<br />
-> GHC.Float.Double<br />
-> GHC.Float.Double<br />
-> GHC.Float.Double<br />
-> GHC.Prim.Double#<br />
-> [GHC.Float.Double]<br />
<br />
Hmm, I certainly don't want boxed doubles in such a tight loop (boxed values<br />
are represented as pointers to closures on the heap, unboxed values are raw<br />
machine values).<br />
<br />
=== Strictify ===<br />
<br />
The next step then is to encourage GHC to unbox this loop, by providing some<br />
strictness annotations. So rewrite the loop like this:<br />
<br />
loop k n alt a1 a2 a3 a4 a5 a6 a7 a8 a9<br />
| () !k !n !alt !a1 !a2 !a3 !a4 !a5 !a6 !a7 !a8 !a9 !False = undefined<br />
| k > n = [ a1, a2, a3, a4, a5, a6, a7, a8, a9 ]<br />
| otherwise = loop (k+1) n (-alt)<br />
(a1 + (2/3) ** (k-1))<br />
(a2 + k ** (-0.5))<br />
(a3 + 1 / (k * (k + 1)))<br />
(a4 + 1 / (k*k*k * sin k * sin k))<br />
(a5 + 1 / (k*k*k * cos k * cos k))<br />
(a6 + 1 / k)<br />
(a7 + 1 / (k*k))<br />
(a8 + alt / k)<br />
(a9 + alt / (2 * k - 1)) where x ! y = x `seq` y<br />
<br />
Here the first guard is purely a syntactic trick to inform ghc that the<br />
arguments should be strictly evaluated. I've played a little game here, using<br />
'''!''' for '''`seq`''' is reminiscent of the new bang-pattern proposal for<br />
strictness. Let's see how this compiles. Strictifying all args GHC produces an<br />
inner loop of:<br />
<br />
$sloop_r2WS :: GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> GHC.Prim.Double#<br />
-> [GHC.Float.Double]<br />
<br />
Ah! perfect. Let's see how that runs:<br />
<br />
$ ghc Naive.hs -O2 -no-recomp<br />
$ time ./a.out 2500000<br />
3.000000000 (2/3)^k<br />
3160.817621887 k^-0.5<br />
0.999999600 1/k(k+1)<br />
30.314541510 Flint Hills<br />
42.995233998 Cookson Hills<br />
15.309017155 Harmonic<br />
1.644933667 Riemann Zeta<br />
0.693146981 Alternating Harmonic<br />
0.785398063 Gregory<br />
./a.out 2500000 4.45s user 0.02s system 99% cpu 4.482 total<br />
<br />
=== Crank up the gcc flags ===<br />
<br />
Not too bad. No space leak and quite zippy. But let's see what more can be<br />
done. First, double arithmetic usually (always?) benefits from<br />
-fexcess-precision, and cranking up the flags to gcc:<br />
<br />
paprika$ ghc Naive.hs -O2 -fexcess-precision -optc-O3 -optc-ffast-math -no-recomp<br />
paprika$ time ./a.out 2500000<br />
3.000000000 (2/3)^k<br />
3160.817621887 k^-0.5<br />
0.999999600 1/k(k+1)<br />
30.314541510 Flint Hills<br />
42.995233998 Cookson Hills<br />
15.309017155 Harmonic<br />
1.644933667 Riemann Zeta<br />
0.693146981 Alternating Harmonic<br />
0.785398063 Gregory<br />
./a.out 2500000 3.71s user 0.01s system 99% cpu 3.726 total<br />
<br />
Even better! Now, let's dive into the Core to see if there are any optimisation<br />
opportunites that GHC missed. So add '''-ddump-simpl''' and peruse the output.<br />
<br />
=== Common subexpressions ===<br />
<br />
Looking at the Core, I see firstly that some of the common subexpressions<br />
haven't been factored out:<br />
<br />
case [GHC.Float.Double] GHC.Prim./## 1.0<br />
(GHC.Prim.*## (GHC.Prim.*##<br />
(GHC.Prim.*## (GHC.Prim.*## sc10_s2VS sc10_s2VS) sc10_s2VS)<br />
(GHC.Prim.sinDouble# sc10_s2VS))<br />
(GHC.Prim.sinDouble# sc10_s2VS))<br />
<br />
Multiple calls to '''sin'''. Hmm... And similar for '''cos''' and '''k*k'''. <br />
Simon Peyton-Jones says:<br />
<br />
GHC doesn't do full CSE. It'd be a relatively easy pass for someone to<br />
add, but it can cause space leaks. And it can replace two<br />
strictly-evaluated calls with one lazy thunk:<br />
let { x = case e of ....; y = case e of .... } in ...<br />
==><br />
let { v = e; x = case v of ...; y = case v of ... } in ...<br />
<br />
Instead GHC does "opportunistic CSE". If you have<br />
let x = e in .... let y = e in ....<br />
then it'll discard the duplicate binding. But that's very weak.<br />
<br />
So it looks like we might have to float out the commmon subexpressions by hand.<br />
The inner loop now looks like:<br />
<br />
loop k n alt a1 a2 a3 a4 a5 a6 a7 a8 a9<br />
| () !k !n !alt !a1 !a2 !a3 !a4 !a5 !a6 !a7 !a8 !a9 !False = undefined<br />
| k > n = [ a1, a2, a3, a4, a5, a6, a7, a8, a9 ]<br />
| otherwise = loop (k+1) n (-alt)<br />
(a1 + (2/3) ** (k-1))<br />
(a2 + k ** (-0.5))<br />
(a3 + 1 / (k * (k + 1)))<br />
(a4 + 1 / (k3 * sk * sk))<br />
(a5 + 1 / (k3 * ck * ck))<br />
(a6 + 1 / k)<br />
(a7 + 1 / k2)<br />
(a8 + alt / k)<br />
(a9 + alt / (2 * k - 1))<br />
where sk = sin k<br />
ck = cos k<br />
k2 = k * k<br />
k3 = k2 * k<br />
x ! y = x `seq` y<br />
<br />
looking at the Core shows the sins are now allocated and shared:<br />
<br />
let a9_s2MI :: GHC.Prim.Double#<br />
a9_s2MI = GHC.Prim.sinDouble# sc10_s2Xa<br />
<br />
So the common expressions are floated out, and it now runs:<br />
<br />
paprika$ time ./a.out 2500000 <br />
3160.817621887 k^-0.5<br />
0.999999600 1/k(k+1)<br />
30.314541510 Flint Hills<br />
42.995233998 Cookson Hills<br />
15.309017155 Harmonic<br />
1.644933667 Riemann Zeta<br />
0.693146981 Alternating Harmonic<br />
0.785398063 Gregory<br />
./a.out 2500000 3.29s user 0.00s system 99% cpu 3.290 total<br />
<br />
Faster. So we gained 12% by floating out those common expressions.<br />
<br />
See also the [[GCD inlining strictness and CSE]] for another example of<br />
where CSE should be performed to improve performance.<br />
<br />
=== Strength reduction ===<br />
<br />
Finally, another trick -- manual <br />
[http://en.wikipedia.org/wiki/Strength_reduction strength reduction]. When I checked the C<br />
entry, it used an integer for the k parameter to the loop, and cast it<br />
to a double for the math each time around, so perhaps we can make it an<br />
Int parameter. Secondly, the alt parameter only has it's sign flipped<br />
each time, so perhaps we can factor out the alt / k arg (it's either 1 /<br />
k or -1 on k), saving a division. Thirdly, '''(k ** (-0.5))''' is just a<br />
slow way of doing a '''sqrt'''.<br />
<br />
The final loop looks like:<br />
<br />
loop i n alt a1 a2 a3 a4 a5 a6 a7 a8 a9<br />
| i !n !alt !a1 !a2 !a3 !a4 !a5 !a6 !a7 !a8 !a9 !False = undefined -- strict<br />
| k > n = [ a1, a2, a3, a4, a5, a6, a7, a8, a9 ]<br />
| otherwise = loop (i+1) n (-alt)<br />
(a1 + (2/3) ** (k-1))<br />
(a2 + 1 / sqrt k)<br />
(a3 + 1 / (k * (k + 1)))<br />
(a4 + 1 / (k3 * sk * sk))<br />
(a5 + 1 / (k3 * ck * ck))<br />
(a6 + dk)<br />
(a7 + 1 / k2)<br />
(a8 + alt * dk)<br />
(a9 + alt / (2 * k - 1))<br />
where k3 = k2*k; k2 = k*k; dk = 1/k; k = fromIntegral i :: Double<br />
sk = sin k; ck = cos k; x!y = x`seq`y<br />
<br />
Checking the generated C code (for another tutorial, perhaps) shows that the<br />
same C operations are generated as the C entry uses.<br />
<br />
And it runs:<br />
$ time ./i 2500000<br />
3.000000200 (2/3)^k<br />
3186.765000000 k^-0.5<br />
0.999852700 1/k(k+1)<br />
30.314493000 Flint Hills<br />
42.995068000 Cookson Hills<br />
15.403683000 Harmonic<br />
1.644725300 Riemann Zeta<br />
0.693137470 Alternating Harmonic<br />
0.785399100 Gregory<br />
./i 2500000 2.37s user 0.01s system 99% cpu 2.389 total<br />
<br />
A big speedup!<br />
<br />
This entry in fact <br />
[http://shootout.alioth.debian.org/gp4/benchmark.php?test=partialsums&lang=all runs] <br />
faster than hand optimised (and vectorised) GCC! And is only slower than<br />
optimised Fortran. Lesson: Haskell can be very, very fast.<br />
<br />
So, by carefully tweaking things, we first squished a space leak, and then<br />
gained another 45%.<br />
<br />
=== Summary ===<br />
<br />
* Manually inspect the Core that is generated<br />
* Use strictness annotations to ensure loops are unboxed<br />
* Watch out for optimisations such as CSE and strength reduction that are missed<br />
* Read the generated C for really tight loops.<br />
* Use -fexcess-precision and -optc-ffast-math for doubles<br />
<br />
== Parameters ==<br />
<br />
On x86 (possibly others), adding parameters to a loop is rather<br />
expensive, and it can be a large win to "hide" your parameters in a<br />
mutable array. (Note that this is the kind of thing quite likely to<br />
change between GHC versions, so measure before using this trick!)<br />
<br />
== Pattern matching ==<br />
<br />
On rare occasions pattern matching can give improvements in code that<br />
needs to repeatedly take apart data structures. This code:<br />
<br />
flop :: Int -> [Int] -> [Int]<br />
flop n xs = rs<br />
where (rs, ys) = fl n xs ys<br />
fl 0 xs ys = (ys, xs)<br />
fl n (x:xs) ys = fl (n-1) xs (x:ys)<br />
<br />
Can be rewritten to be faster (and more ugly) as:<br />
<br />
flop :: Int -> [Int] -> [Int]<br />
flop 2 (x1:x2:xs) = x2:x1:xs<br />
flop 3 (x1:x2:x3:xs) = x3:x2:x1:xs<br />
flop 4 (x1:x2:x3:x4:xs) = x4:x3:x2:x1:xs<br />
flop 5 (x1:x2:x3:x4:x5:xs) = x5:x4:x3:x2:x1:xs<br />
flop 6 (x1:x2:x3:x4:x5:x6:xs) = x6:x5:x4:x3:x2:x1:xs<br />
flop 7 (x1:x2:x3:x4:x5:x6:x7:xs) = x7:x6:x5:x4:x3:x2:x1:xs<br />
flop 8 (x1:x2:x3:x4:x5:x6:x7:x8:xs) = x8:x7:x6:x5:x4:x3:x2:x1:xs<br />
flop 9 (x1:x2:x3:x4:x5:x6:x7:x8:x9:xs) = x9:x8:x7:x6:x5:x4:x3:x2:x1:xs<br />
flop 10 (x1:x2:x3:x4:x5:x6:x7:x8:x9:x10:xs) = x10:x9:x8:x7:x6:x5:x4:x3:x2:x1:xs<br />
flop n xs = rs<br />
where (rs, ys) = fl n xs ys<br />
fl 0 xs ys = (ys, xs)<br />
fl n (x:xs) ys = fl (n-1) xs (x:ys)<br />
<br />
== Arrays ==<br />
<br />
If you are using array access and GHC primops, do not be too eager to<br />
use raw Addr#esses; MutableByteArray# is just as fast and frees you<br />
from memory management.<br />
<br />
== Memory allocation and arrays ==<br />
<br />
When you are allocating arrays, it may help to know a little about GHC's memory allocator. There are lots of deatils in [http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage The GHC Commentary]), but here are some useful facts:<br />
<br />
* For larger objects ghc has an allocation granularity of 4k. That is it always uses a multiple of 4k bytes, which can lead to wasteage of up to 4k per array. Furthermore, a byte array has some overhead: it needs one word for the heap cell header and another for the length. So if you allocate a 4k byte array then it uses 8k. So the trick is to allocate 4k - overhead. This is what the Data.ByteString library does<br />
<br />
* GHC allocates memory from the OS in units of a "megablock", currently 1Mbyte. So if you allocate a 1Mb array, the storage manager has to allocate 1Mb + overhead, which will cause it to allocate a 2Mb megablock. The surplus will be returned to the system in the form of free blocks, but if all you do is allocate lots of 1Mb arrays, you'll waste about half the space because there's never enough contiguous free space to contain another 1Mb array. Similar problem for 512k arrays: the storage manager allocates a 1Mb block, and returns slightly less than half of it as free blocks, so each 512k allocation takes a whole new 1Mb block.<br />
<br />
== Rewrite rules ==<br />
<br />
Algebraic properties in your code might be missed by the GHC optimiser.<br />
You can use [[Playing by the rules|user-supplied rewrite rules]] to<br />
teach the compiler to optimise your code using domain-specific<br />
optimisations.</div>Barubaryhttps://wiki.haskell.org/index.php?title=Xmonad/Frequently_asked_questions&diff=16686Xmonad/Frequently asked questions2007-11-07T00:46:41Z<p>Barubary: </p>
<hr />
<div>{{xmonad}}<br />
<br />
''xmonad: frequently asked questions''<br />
<br />
==What build dependencies does xmonad have?==<br />
<br />
The [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmonad<br />
hackage page for xmonad] lists all dependencies, including:<br />
<br />
* Standard Haskell libraries (you might already have these installed):<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Cabal Cabal]<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/mtl mtl]<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/unix unix]<br />
<br />
* Haskell X11 bindings:<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/X11 X11]<br />
<br />
* C libraries:<br />
** libX<br />
** libXext<br />
** libXinerama<br />
<br />
You likely have these already if you've built any programs for X.<br />
<br />
<br />
==Can I install without root permission?==<br />
<br />
Yes, the Haskell libraries that xmonad depends on can all by<br />
installed in the user package database. Simply append --user <br />
to the install phase:<br />
<br />
$ runhaskell Setup.hs install --user<br />
<br />
The library will be registered in your ~/.ghc/ database.<br />
<br />
==How do I configure xmonad?==<br />
<br />
By editing the Config.hs file, a Haskell source file. You<br />
can use any Haskell you want in this module. To have your<br />
changes take effect, recompile xmonad, reinstall it, and<br />
either restart (mod-q) or exit X, and log back<br />
in.<br />
<br />
[[Xmonad/Config_archive|Example configurations]] are available on the wiki.<br />
<br />
Note that when reinstalling, cabal might prevent you from<br />
overwriting the running xmonad binary:<br />
<br />
Installing: /home/dons/lib/xmonad-0.2/ghc-6.6 &amp; /home/dons/bin xmonad-0.2...<br />
copy /usr/obj/cabal/xmonad/xmonad to /home/dons/bin/xmonad<br />
*** Exception: /home/dons/bin/xmonad: copyFile: resource busy (Text file busy)<br />
<br />
The solution is to remove the old xmonad binary before install. <br />
<br />
rm `which xmonad`<br />
<br />
This is not required if you're using newer Cabal versions.<br />
<br />
==Does xmonad support a statusbar?==<br />
<br />
Yes. Arbitrary external programs may be used as a statusbar. See for<br />
example [http://gotmor.googlepages.com/dzen dzen] or [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmobar xmobar], an extensible status bar.<br />
<br />
xmonad lets you use any application as a 'statusbar', as long as it is<br />
visible in a given 'gap' on the screen, and has the override-redirect<br />
property set to true. Many status bar/dock programs already set this<br />
property, for example, dzen. To set other applications, you can<br />
sometimes use normal X resources. For example, to use xclock, launch it<br />
with <br />
<br />
xclock -digital -xrm '*overrideRedirect: True' -geometry 1024x30+0+0<br />
<br />
And set a gap of (30,0,0,0) in Config.hs. A similar trick can be done for xsystray.<br />
<br />
You can see screenshots of statusbars on [[Xmonad/Screenshots|the screenshots page]].<br />
<br />
==How can I use xmonad with a display manager? (xdm, kdm, gdm)==<br />
<br />
The simplest way is to create or modify your ~/.xsession file to run<br />
xmonad. If you don't already have a .xsession, the minimal example<br />
looks like:<br />
<br />
xmonad<br />
<br />
This requires that the xmonad executable (or a symlink to it) is in a<br />
directory in your $PATH. Alternatively, you can use the full path to<br />
xmonad. People using 'startx' can use these example <br />
[http://code.haskell.org/XMonadContrib/scripts/xinitrc xinitrc] and <br />
[http://code.haskell.org/XMonadContrib/scripts/run-xmonad.sh run-xmonad]<br />
scripts.<br />
<br />
If you are using xdm, you're done. Login and enjoy xmonad.<br />
<br />
If you're using kdm or gdm (KDE and GNOME's display mangers, respectively),<br />
you're almost done. When logging in, select the entry that says "xsession"<br />
or "default session" from the menu in order to use your ~/.xsession to<br />
start xmonad.<br />
<br />
Alternatively, if you want a menu entry specifically for xmonad, create a<br />
file named "xmonad.desktop" in your /usr/share/xsessions (location varies<br />
by distribution) directory. For example:<br />
<br />
[Desktop Entry]<br />
Encoding=UTF-8<br />
Name=xmonad<br />
Comment=This session starts xmonad<br />
Exec=/usr/local/bin/xmonad<br />
Type=Application<br />
<br />
Replace the "Exec=..." line with the actual path to your xmonad executable,<br />
and you should be able to login by selecting "xmonad" as a session from the<br />
menu in gdm/kdm.<br />
<br />
For instructions on using gdm to launch a full GNOME session with xmonad as<br />
the window manager [http://xmonad.org/gnome.html read this].<br />
<br />
==Using a dock client==<br />
<br />
As of version 0.2, dock clients (such as gkrellm) aren't specially<br />
supported. They will be treated as a normal window. It is possible to<br />
use them by explicitly unmanaging the window, after moving it into a gap<br />
space. Dock clients are fully supported in version 0.4 and later.<br />
<br />
==X11 fails to find libX11 or libXinerama==<br />
<br />
Cabal has difficulty locating library directories on some<br />
platforms (such as the Mac or RHEL4). First, locate the<br />
directory that contains libX11.so (libX11.dylib on Mac OS<br />
X). Add the following line to the .cabal file for the<br />
package:<br />
<br />
extra-lib-dirs: /your/path/here/<br />
<br />
For example, on a 64 bit machine you might need to add:<br />
<br />
extra-lib-dirs: /usr/X11R6/lib/lib64<br />
<br />
You can also add the paths to your .buildinfo file, or set the<br />
LD_LIBRARY_PATH environment variable.<br />
<br />
==xmonad does not detect my multi-head setup==<br />
<br />
You may not have the Xinerama development files installed, install them,<br />
then watch the configure output for X11. Look for the following<br />
lines:<br />
<br />
checking X11/extensions/Xinerama.h usability... yes<br />
checking X11/extensions/Xinerama.h presence... yes<br />
checking for X11/extensions/Xinerama.h... yes<br />
<br />
Be sure to clean and rebuild xmonad after building and installing X11.<br />
<br />
==Main.hs:175:8: Not in scope: data constructor `ConfigureEvent'==<br />
<br />
When building a darcs version of xmonad, you may also need to use a<br />
darcs version of the X11 library. That is available from:<br />
<br />
darcs get http://darcs.haskell.org/X11<br />
<br />
==Missing X11 headers==<br />
<br />
Your build will fail if you've not installed the X11 C library headers<br />
at some point. ./configure for the Haskell X11 library will fail. To<br />
install the X11 C libs:<br />
<br />
* debian<br />
<br />
apt-get install libx11-dev<br />
<br />
* ubuntu<br />
<br />
...<br />
<br />
==Rebinding the mod key==<br />
<br />
xmonad uses 'alt', actually mod1, as the default modifier. You may<br />
bind to other mod keys by editing Config.hs' modMask value, or by<br />
using xmodmap to rebind a key to mod1. The apple command key can be<br />
rebound to mod1 in this way. Use xmodmap to find what key your mod1<br />
is bound to, as well.<br />
<br />
You can rebind the Caps Lock key, to mod, if you wish. See this<br />
[http://www.suckless.org/pipermail/dwm/2007-June/002715.html mailing list item].<br />
<br />
If your new key binding doesn't appear to work, double check it doesn't<br />
clash with an existing binding.<br />
<br />
==Saving layout==<br />
<br />
xmonad will remember your workspace layouts during dynamic restart<br />
(mod-q), but not when quitting X altogether. Note that this means <br />
if you add or remove layouts to the config.hs file, the changes won't be<br />
noticed during a hot-restart (the state from the previous session will<br />
be used).<br />
<br />
You can reinitialise the xmonad state dynamically with mod-space.<br />
<br />
==Startup programs==<br />
<br />
You may launch programs at startup in the usual X manner: by adding<br />
them to your .xsession or .Xinitrc. For example, the following<br />
.xsession file launches 'unclutter' to hide the cursor, xpmroot to<br />
set the background image, xmodmap to rebind caps lock to ctrl. It<br />
then launches a status bar program with dzen, before finally<br />
launching xmonad:<br />
<br />
# .xsession<br />
unclutter -idle 1 &amp;<br />
xpmroot ~/.bg/407511721_eb8559457c_o.xpm &amp;<br />
xrdb -merge .Xresources<br />
<br />
xmodmap -e "remove Lock = Caps_Lock"<br />
xmodmap -e "keysym Caps_Lock = Control_L"<br />
xmodmap -e "add Control = Control_L"<br />
<br />
status | dzen2 -ta r -fg '#a8a3f7' \<br />
-bg '#3f3c6d' \<br />
-fn '-*-terminus-medium-r-normal--16-*' \<br />
-e "button1=exec:xterm" &amp; <br />
urxvt &amp;<br />
<br />
$HOME/bin/xmonad<br />
<br />
==Losing text when resizing xterms==<br />
<br />
Being a dynamic tiling window manager, xmonad, like ion or dwm, makes<br />
heavy use of resizing. Poor clients such as xterm, might not take well<br />
to resizing and will require explicit resize events to be sent (Ctrl-L).<br />
This however, can cause the buffer to be cleared. To avoid this, several<br />
users recommend urxvt (rxvt-unicode), which handles resizing much<br />
better.<br />
<br />
==Dynamic restart==<br />
<br />
The dynamic reconfigure and restart feature (mod-q) assumes that<br />
xmonad is in your $PATH environment. If it isn't, restarting will<br />
have no effect.<br />
<br />
==Some keys not working==<br />
<br />
If you've an unusual keyboard, X may not know precisely which keys<br />
you've bound xmonad actions to. An example is when you've use a<br />
French keyboard. You may need to set your own mod key, or use<br />
different key bindings in Config.hs. See <br />
[http://thread.gmane.org/gmane.comp.lang.haskell.xmonad/1862/focus=1863 this thread]<br />
for advice on rebindings keys.<br />
<br />
==Firefox's annoying popup downloader==<br />
<br />
Some applications, notably Firefox 1 and 2, create tranisent windows not<br />
set with the transient property. (e.g. firefox's download manager). When<br />
these windows appear, they can take focus and be annoying. For the case<br />
of firefox, the 'Download Statusbar' extension is useful for disabling<br />
this annoying UI feature.<br />
<br />
==Copy and Paste on the Mac==<br />
<br />
When using X11 for Mac OS X, and you switch from the quartz WM to<br />
xmonad, you can lose copy/paste functionality between X windows and<br />
normal Mac apps. To fix this, and restore copy and paste, add<br />
<br />
<br />
quartz-wm --only-proxy &<br />
<br />
<br />
in your .xinitrc above the line that runs xmonad. It will capture and<br />
syncronize copy/paste events in both environments. More specifically,<br />
it mirrors OS X copy actions into both PRIMARY and CLIPBOARD, but only<br />
CLIPBOARD into OS X paste.<br />
<br />
==Building xmonad with GHC 6.8==<br />
<br />
The ghc version 6.8 uses a smaller base library, with some modules<br />
xmonad depends on moved into the 'containers' package. Additionally,<br />
some language extension flags have changed.<br />
<br />
To build xmonad 0.4 with ghc 6.8, you'll need to amend your .cabal file<br />
slightly, to something like:<br />
<br />
-build-depends: base>=2.0, X11>=1.3.0, mtl>=1.0, unix>=1.0<br />
+build-depends: base>=2.0, X11>=1.3.0, mtl>=1.0, unix>=1.0, containers<br />
<br />
-ghc-options: -funbox-strict-fields -O2 -fasm -Wall -optl-Wl,-s<br />
+ghc-options: -funbox-strict-fields -O2 -fasm -Wall -optl-Wl,-s -XPatternGuards -XExistentialQuantification -XMultiParamTypeClasses -XTypeSynonymInstances -fglasgow-exts<br />
<br />
Alternatively, you can update to cabal 1.2, and use a version of xmonad<br />
more recent than 0.4, which will build with either ghc 6.6.x or ghc 6.8.<br />
<br />
==Setting the X cursor==<br />
<br />
By default xmonad doesn't set a particular X cursor, which usually<br />
means the default X cursor will be used by the system. To set your<br />
own custom cursor, use the xsetroot program, as follows, from your<br />
startup file:<br />
<br />
xsetroot -cursor_name left_ptr<br />
<br />
For example, to get nice left-pointing arrow head cursor.<br />
<br />
==Problems with Java applications==<br />
<br />
The Java gui toolkit has a hardcoded list of so-called "non-reparenting"<br />
window managers. xmonad is not on this list (nor are many of the newer<br />
window managers). Attempts to run Java applications may result in `grey<br />
blobs' where windows should be, as the Java gui code gets confused.<br />
<br />
To work around this silly restriction, you can attempt to fake the<br />
window manager used by setting the environment variable:<br />
<br />
AWT_TOOLKIT=MToolkit<br />
<br />
This seems to fix at least MATLAB and cgoban3. It also fixes an issue<br />
with Java gui applications where menus are not "selectable". Clicking on<br />
the menu item opens the dropdown list of options but you can't select<br />
one. <br />
<br />
Using the free blackdown java runtime also seems to work correctly.<br />
<br />
==Compiling xmonad on PowerPC and compiler is not interactive==<br />
<br />
If you have ghc installed and are trying to compile xmonad and your compiler <br />
complains about not being interactive, never fear. To compile Setup.hs simply type:<br />
<br />
ghc --make Setup.hs -o Setup<br />
<br />
Now you can:<br />
<br />
./Setup configure<br />
./Setup build<br />
sudo ./Setup install<br />
<br />
If during the build process ghc complains about the "impossible<br />
happening", and mentions that you should change something to "-fvia-C",<br />
just edit the *.cabal file replacing the line that sets the arguments<br />
for ghc, changing "-fasm" to "-fvia-C".<br />
<br />
== Cabal: Executable stanza starting with field 'flag small_base description' ==<br />
<br />
The darcs version after xmonad 0.4 switched to requiring Cabal 1.2 to<br />
build xmonad. You '''must''' have Cabal 1.2 or newer to build xmonad<br />
older than 0.4. It will work fine with ghc 6.6.1, and you do not need to<br />
updated ghc. Get cabal from Hackage:<br />
<br />
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Cabal<br />
<br />
Build and install as usual, then rebuild xmonad.<br />
<br />
To build Cabal with ghc 6.6.1 you will also need the filepath library,<br />
which is also (of course) available from hackage:<br />
<br />
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/filepath<br />
<br />
== Changes to the config file ignored ==<br />
<br />
Both ghc and xmonad must be in your $PATH for reconfiguration to work.<br />
<br />
When changing the config.hs (0.4) or xmonad.hs (0.5) and restarting <br />
with mod-q, xmonad will attempt to exec the xmonad binary. This means<br />
it must be in your $PATH environment variable, or the exec will fail<br />
silently and the old xmonad instance keeps running.<br />
<br />
With xmonad 0.5 and later, mod-q will also call ghc on your<br />
~/.xmonad/xmonad.hs file, and will continue with defaults if ghc is not<br />
found.<br />
<br />
<br />
[[Category:XMonad]]</div>Barubary