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

RandomCover use a @nogc buffer to store already chosen results #6576

Merged
merged 9 commits into from Jul 15, 2018
Merged

RandomCover use a @nogc buffer to store already chosen results #6576

merged 9 commits into from Jul 15, 2018

Conversation

ghost
Copy link

@ghost ghost commented Jun 10, 2018

The life time of the array storing the already chosen results is deterministic so there's no need to use a built-in array, instead a small dedicated array is used. This change is far from making the randomCover family of functions @nogc but at least it avoids an alloc (fundamentally, issue 14001 is blocked by exceptions in uniform and in the different RNGs).

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @bbasile! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the annotated coverage diff directly on GitHub with CodeCov's browser extension
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub fetch digger
dub run digger -- build "master + phobos#6576"

@ghost ghost requested a review from wilzbach as a code owner June 10, 2018 13:23
Copy link
Member

@wilzbach wilzbach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the motivation, but it somehow feels like we are re-inventing the wheel.
There shouldn't be a need to code a custom struct every time we want sth. to be @nogc :/
Could we at least maybe use stdx.allocator?

std/random.d Outdated
void* nbuffer = malloc(_length);
if (nbuffer is null)
assert(0, emsg);
buffer = memmove(nbuffer, buffer, _length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not makeArray?

@ghost
Copy link
Author

ghost commented Jun 10, 2018

Could we at least maybe use stdx.allocator?

I thought to this and concluded that it's not a good idea to use the allocators in phobos until their are promoted to std. (note that they are not used at all in phobos).

There shouldn't be a need to code a custom struct every time we want sth. to be @nogc

Yeah. Obviously i'd use std.container.array.Array if it hasn't this hilarious constraint that is, every type is allowed as element but not bool.

@wilzbach
Copy link
Member

I thought to this and concluded that it's not a good idea to use the allocators in phobos until their are promoted to std. (note that they are not used at all in phobos).

FWIW that shouldn't be a problem and for example std.file is using std.experimental.checkedint already.
As long as it's used internally, we should be good. Imho it's even good if we start to use it internally because only by intensive use we can detect flaws.

Obviously i'd use std.container.array.Array if it hasn't this hilarious constraint that is, every type is allowed as element but not bool.

Ouch. Does anyone know about the history of this constraint?
Was the idea that BitArray is a replacement?

@aG0aep6G
Copy link
Contributor

Yeah. Obviously i'd use std.container.array.Array if it hasn't this hilarious constraint that is, every type is allowed as element but not bool.

The constraint is just on the first template, because there's another one that's specialized for bool: https://dlang.org/phobos/std_container_array.html#.Array.2

It would probably be less confusing if there was just one template, with the specialization inside.

@ghost
Copy link
Author

ghost commented Jun 10, 2018

Array!bool is not @nogc enough anyway, there are plenty of compile errors when used.

@ghost
Copy link
Author

ghost commented Jun 10, 2018

The new custom type can be made more useful by allowing bit packed array of bool for small length (up to size_t * 8 elements to cover.

@ghost
Copy link
Author

ghost commented Jun 12, 2018

@wilzbach, maybe you could reconsider your POV. Now that a field of bits is used the custom type is really interesting for small (<= 64) ranges to cover.

std/random.d Outdated

this(this) nothrow @nogc @trusted
{
import core.stdc.stdlib : malloc;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although since you assert(0) if they fail, it would be justifiable to call "locally pureified" malloc/etc. directly.

Copy link
Author

@ghost ghost Jun 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've moved to onOutOfMemoryErrorNoGC.
Now there's a dilemma : pure allocs and asserts or static exceptions and impure allocs

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onOutOfMemoryError is @nogc nothrow pure, so why not use it instead of onOutOfMemoryErrorNoGC?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed.

std/random.d Outdated
{
void* nbuffer = malloc(_length);
if (nbuffer is null)
assert(0, emsg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In places like this it seems like the convention is to use onOutOfMemoryError:

if (nbuffer is null)
{
    onOutOfMemoryError();
    assert(0);
}

...but this has the downside that your custom message would be lost.

std/random.d Outdated
if (nbuffer is null)
assert(0, emsg);
buffer = memmove(nbuffer, buffer, _length);
if (buffer is null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check doesn't make sense. Cut & paste error?

std/random.d Outdated
}
}

this(size_t value) nothrow @nogc @trusted @property
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameter name should hint at purpose.

@ghost
Copy link
Author

ghost commented Jun 13, 2018

Actually i think this could close 14001. While RandomCover is still not @nogc every suggestion made in there is implemented.

std/random.d Outdated
private immutable size_t _length;
private immutable bool hasPackedBits;

this(this) pure nothrow @nogc @trusted
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe an explicit (or disabled) opAssign is also required.

std/random.d Outdated
void* nbuffer = pureMalloc(_length);
if (nbuffer is null)
onOutOfMemoryError();
buffer = memmove(nbuffer, buffer, _length);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use memcpy here instead of memmove because the destination and source cannot overlap.

Copy link
Member

@wilzbach wilzbach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I didn't object to this PR, I just said that it would be nice if we could be reusing existing containers (instead of rolling yet another custom-built one).
I had a brief look at the bool-version of Array and I agree that it would take quite some effort to make it as efficient/specialized like this container.
Also, hopefully the new collections library gets into stdx soon, s.t. we can use these containers in the future ...

@n8sh n8sh added 72h no objection -> merge The PR will be merged if there are no objections raised. optimization auto-merge labels Jul 10, 2018
@dlang-bot dlang-bot merged commit c7b1cf1 into dlang:master Jul 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
72h no objection -> merge The PR will be merged if there are no objections raised. auto-merge optimization
Projects
None yet
4 participants