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

V.enumFromTo is only fast for Int, not Word32 #21

Closed
nh2 opened this issue Apr 29, 2014 · 5 comments
Closed

V.enumFromTo is only fast for Int, not Word32 #21

nh2 opened this issue Apr 29, 2014 · 5 comments

Comments

@nh2
Copy link
Member

nh2 commented Apr 29, 2014

In https://groups.google.com/d/msg/haskell-cafe/Ms4sKZBwTtw/55CFywSytBQJ I benchmark different alternatives to forM_ [1..n] to each other.

When looking at V.forM_ (V.enumFromTo 1 n), we noticed that this gets only optimised away to a fast loop when using Vector Int. With Vector Word32, it's 5 times slower.

What @JohnLato thinks about this:

Ahh, you made me look at the core again. I think this is related to your observation about V.enumFromTo being the same as V.fromList. With Word32 the generated core shows that this goes via a list representation instead of a nice loop. Which makes me suspect there's some RULE that applies to Stream.enumFromTo that is firing in the first case but not the second. And if I build both versions with -ddump-rule-firings, indeed I see that the Int version has

Rule fired: enumFromTo [Stream]

With nothing comparable for the Word32 version. I'd imagine if you grep for that in the Vector sources, you'd find something interesting.

It would be great if somebody familiar with the vector library could check out whether there are indeed RULES missing for types like Word32.

@basvandijk
Copy link
Member

The problem probably occurs in Data.Vector.Fusion.Bundle.Monadic or Data.Vector.Fusion.Stream.Monad which both define RULES for enumFromTo.

@dolio
Copy link
Contributor

dolio commented May 26, 2014

Can you check your benchmarks with the latest vector source? I merged a patch that is supposed to have fixed some RULES.

However, I actually don't expect it to work for Word32. I've been looking at the core for a simple test, and the behavior is very strange. There's a rule for Word32 that isn't firing, but the analogous rule fires for many other cases. Int16, Word16, Word64, Int64 and Int32 all work fine, but the Word32 rule does not fire and I'm not sure why. The Word32 and Int32 rules are in the same CPP block, so I don't see what the difference is yet.

@dolio
Copy link
Contributor

dolio commented May 26, 2014

Never mind, I figured out the problem. WORD_SIZE_IN_BITS was undefined due to a missing MachDeps.h include.

If you try the latest, you should be getting good performance on all types, I think. If you can confirm, I'll close the bug.

@nh2
Copy link
Member Author

nh2 commented May 26, 2014

If you try the latest

I would like to, but I cannot figure out how to install vector from git (0.11) and the benchmark at the same time:

The benchmark dependencies (criterion) have vector < 0.11 in various places. I tried Cabal's --allow-newer flag, but that seems to lift all upper bounds of all packages, which gives me another build error.

How can I lift only the upper bounds on vector?

nh2 added a commit to nh2/loop that referenced this issue May 26, 2014
@nh2
Copy link
Member Author

nh2 commented May 26, 2014

While my question above persists, I managed to test this by cheating, setting vector's version to 0.10.9.100.

Benchmark results:

So this is fixed.

@nh2 nh2 closed this as completed May 26, 2014
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

Successfully merging a pull request may close this issue.

3 participants