Skip to content

Commit

Permalink
Excessive pointer chasing done
Browse files Browse the repository at this point in the history
  • Loading branch information
doyougnu committed Jun 24, 2022
1 parent ec0293f commit 01518e1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
37 changes: 32 additions & 5 deletions src/Preliminaries/what_makes_fast_hs.rst
Expand Up @@ -142,10 +142,21 @@ Excessive Pointer Chasing
What is Excessive Pointer Chasing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Excessive pointer chasing is the enemy of any high performance Haskell program,
and presents itself in various forms; most of which Haskeller's are familiar
with to some degree. These include memory leaks during folds (strict and lazy),
for example [#]_:
Excessive pointer chasing is a form of superfluous computation; our program is
doing more work than it needs in order to compute the result. It occurs anytime
our programs dereference a pointer to retrieve a value instead of just
referencing the value itself, thereby creating an extra layer of unnecessary
indirection. In Haskell programs this most often occurs when we write programs
without thinking about their memory representation; and especially around
laziness. As such, most of these instances are well known and have floated
around the community for some time.


How does excessive pointer chasing slow down runtime performance?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The classic example of excessive pointer chasing is memory leaks that result
from folds that are overly lazy, for example [#]_:

.. code-block:: haskell
:caption: mean, calculated with a lazy left fold
Expand Down Expand Up @@ -219,16 +230,32 @@ that each ``Counter`` holds a pointer to an ``Int`` on the heap *not* a pointer
to an ``Int`` directly. We can instruct GHC remove the heap indirection with the
`unpack
<https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/exts/pragmas.html?highlight=unpack#unpack-pragma>`_
pragma and a bang pattern:

.. code-block:: haskell
data Counter = Counter {-# UNPACK -#} !Int

This pragma instructs GHC to store the contents of ``Int`` directly in the
``Counter`` constructor, rather than storing a pointer to an ``Int`` on the heap
in the constructor. We'll return to these fixes in the :ref:`Excessive Pointer
Chasing` section.

.. _canonical-closure-alloc:

Excessive Closure Allocation
----------------------------

What is Excessive Closure Allocation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

xcessive :term:`Closure` allocation is :cite:p:`GHCInliner` and :cite:t:`GHCInliner`



How does Excessive Closure Allocation slow down runtime performance
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. _canonical-domain-modeling:

Poor Domain Modeling
Expand Down
8 changes: 4 additions & 4 deletions src/glossary.rst
Expand Up @@ -16,20 +16,20 @@ Glossary
<https://en.wikipedia.org/wiki/Lambda_calculus_definition#Weak_head_normal_form>`_
for more.

Boxed Value
Boxed : Levity
A Boxed value is a value that is represented by a pointer to the heap.

Unboxed Value
Unboxed : Levity
An UnBoxed value is a value that is represented by the value itself.
UnBoxed values therefore cannot be lazy, like boxed values.

Lifted Type
Lifted : Levity
A Lifted type is a type that contains the value :math:`\bot`;
which represents non-terminating computation. For example, the ``Bool``
type is a set with three values: ``True``, ``False``, and :math:`\bot`.
Therefore ``Bool`` is a Lifted type.

Unlifted Type
Unlifted : Levity
An Unlifted type is a type where :math:`\bot` *is not* an element of that type.

Thunk
Expand Down

0 comments on commit 01518e1

Please sign in to comment.