Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a custom array type for SetM? #928

Open
treeowl opened this issue Feb 2, 2023 · 6 comments
Open

Use a custom array type for SetM? #928

treeowl opened this issue Feb 2, 2023 · 6 comments

Comments

@treeowl
Copy link
Contributor

treeowl commented Feb 2, 2023

I noticed that the marking array we use for DFS doesn't always get unboxed (at least, it didn't in one of my lazy preorder experiments). So I tried making the Functor, Applicative, and Monad instances for SetM explicitly strict in the array. This successfully unboxed it, but unfortunately the effects on performance were somewhat mixed. I suspect the problem may be something like register pressure.

We currently use STUArray s Int Bool for SetM. STUArray is defined

data STUArray s i e = STUArray !i !i !Int (MutableByteArray# s)

In our case, that means we're passing around:

  1. A boxed Int for the lower bound.
  2. A boxed Int for the upper bound.
  3. An unboxed Int# for the array size.

If we use a custom array type, we can remove indirections without so many function arguments. The most extreme version would be

data Markers s = Markers (MutableByteArray# s)

where we store the lower bound in the first word of the byte array and get the array size using getSizeofMutableByteArray#. If I read the GHC heap object layout correctly, this will put the lower bound immediately after the array size, so we'll use at most one cache line for those.

@meooow25
Copy link
Contributor

meooow25 commented Mar 3, 2023

I think we would want to store the size explicitly too, for bounds checks, since the real size would be >= the requested size.

@treeowl
Copy link
Contributor Author

treeowl commented Mar 3, 2023

GHC stores the size. It needs to, for garbage collection. There's a primop to get it.

@meooow25
Copy link
Contributor

meooow25 commented Mar 3, 2023

Yes, but consider that we want to store just one bit, but the MutableByteArray# will be the size of a word. We should ideally error on access beyond that one bit.

@treeowl
Copy link
Contributor Author

treeowl commented Mar 3, 2023

I don't think we need that, do we? We have the Graph, which is a Data.Array and therefore has its size stashed. We can do the bounds check against that, no?

@meooow25
Copy link
Contributor

meooow25 commented Mar 4, 2023

We could do that at dfs yes. If so we might as well not store the lower bound, and check that at the same place. Then we need no checks at all at the MutableByteArray#. Seems a bit extreme though.

@treeowl
Copy link
Contributor Author

treeowl commented Mar 4, 2023

Yes. I guess I wasn't thinking clearly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants