IF-free conception.

K

Ken Brody

(snip)

I might have previously noted that I used to do that in OS/2 in 16
bit mode. (Back to OS/2 1.0, and still supported in 2.x.)

Instead of calling malloc(), I directly called the OS/2 segment
allocation routine to allocate a segment of exactly the right size.

With the ring and global/local bit, each task can only have 8191
segments (segment 0 is special). For the programs I was working on
at the time, I never ran into the limit.

Which currently popular systems allow for this?

Well, "popular" may be up for debate, but SCO allows this. I don't believe
it uses separate segments (actually "selectors", IIRC), but rather the
memory manager to specify which pages are valid within that selector.

See, for example:

uggc://bfe600qbp.fpb.pbz/ra/zna/ugzy.F/znyybp.F.ugzy
 
K

Keith Thompson

Ken Brody said:
On 2/20/2013 8:01 PM, glen herrmannsfeldt wrote: [...]
With the ring and global/local bit, each task can only have 8191
segments (segment 0 is special). For the programs I was working on
at the time, I never ran into the limit.

Which currently popular systems allow for this?

Well, "popular" may be up for debate, but SCO allows this. I don't believe
it uses separate segments (actually "selectors", IIRC), but rather the
memory manager to specify which pages are valid within that selector.

See, for example:

uggc://bfe600qbp.fpb.pbz/ra/zna/ugzy.F/znyybp.F.ugzy

Did you really mean to rot13 the URL?
 
J

Jorgen Grahn

I bet he's talking about Electric Fence, not Valgrind. Valgrind has
its own layer of control between the code and the hardware, and AIUI
doesn't need the MMU to tell it if the memory being accessed exists or
not.

Well, when I used valgrind on the no-if code, it only complained about
the fact that a[child+1] was reading uninitialized memory. It didn't
complain about the fact that the memory was uninitialized because it was
one past the end of a requested allocation, which is a more serious
problem. If there's an option to turn on warnings about the more serious
problem, I'd appreciate knowing what it is.

There's always the manual. And the web site, to check if there are new
options in more recent versions; not unlikely.

I think the idea is that you should deal with all warnings. "Reading
uninitialized memory" is bad enough, since with Valgrind this means
reading /and using/ it. Just reading garbage into an array doesn't
trigger a warning.

/Jorgen
 
J

James Kuyper

On Thu, 2013-02-21, James Kuyper wrote: ....
Which option is that? I didn't notice it at
<http://valgrind.org/docs/manual/mc-manual.html#mc-manual.options>,
which seemed the obvious place to look.
....
Well, when I used valgrind on the no-if code, it only complained about
the fact that a[child+1] was reading uninitialized memory. It didn't
complain about the fact that the memory was uninitialized because it was
one past the end of a requested allocation, which is a more serious
problem. If there's an option to turn on warnings about the more serious
problem, I'd appreciate knowing what it is.

There's always the manual. ...

The link I gave was for the online manual.
... And the web site, to check if there are new
options in more recent versions; not unlikely.

Is there a more up-to-date source of information about the command line
options than the online manual?
I think the idea is that you should deal with all warnings. "Reading
uninitialized memory" is bad enough, since with Valgrind this means
reading /and using/ it. Just reading garbage into an array doesn't
trigger a warning.

Not really - if you read uninitialized memory using a data type known
not to have trap representations (either because the standard says so,
or because the compiler's documentation does), reading it is perfectly
safe; it has an unspecified value, but a valid one for the type. Reading
past the end of an array has undefined behavior, which is much worse.
 
J

Jorgen Grahn

On 02/21/2013 02:10 PM, Jorgen Grahn wrote:
On Thu, 2013-02-21, James Kuyper wrote: ...
Which option is that? I didn't notice it at
<http://valgrind.org/docs/manual/mc-manual.html#mc-manual.options>,
which seemed the obvious place to look. ...
Well, when I used valgrind on the no-if code, it only complained about
the fact that a[child+1] was reading uninitialized memory. It didn't
complain about the fact that the memory was uninitialized because it was
one past the end of a requested allocation, which is a more serious
problem. If there's an option to turn on warnings about the more serious
problem, I'd appreciate knowing what it is.

There's always the manual. ...

The link I gave was for the online manual.
... And the web site, to check if there are new
options in more recent versions; not unlikely.

Is there a more up-to-date source of information about the command line
options than the online manual?

No, I'm not claiming there is. I missed your link to the
documentation, and tried to be helpful.

That seems to be the 'valgrind --memcheck' documentation, by the way.
Remember to check if they have released some other checker which does
more of what you want.
Not really - if you read uninitialized memory using a data type known
not to have trap representations (either because the standard says so,
or because the compiler's documentation does), reading it is perfectly
safe; it has an unspecified value, but a valid one for the type. Reading
past the end of an array has undefined behavior, which is much worse.

Ok, but I don't see how that relates to what I wrote. I'm not claiming
that Valgrind warns about just /reading/ uninitialized memory, and I
agree that it's a harmless situation.

/Jorgen
 
B

Bart van Ingen Schenau

[Re: an option, incorrectly claimed to be a valgrind option, ensuring
that attempted access to a memory one-past-the end of an array would
generate error messages.]
...
Well, when I used valgrind on the no-if code, it only complained
about the fact that a[child+1] was reading uninitialized memory. It
didn't complain about the fact that the memory was uninitialized
because it was one past the end of a requested allocation, which is
a more serious problem. If there's an option to turn on warnings
about the more serious problem, I'd appreciate knowing what it is. ...
I think the idea is that you should deal with all warnings. "Reading
uninitialized memory" is bad enough, since with Valgrind this means
reading /and using/ it. Just reading garbage into an array doesn't
trigger a warning.

Not really - if you read uninitialized memory using a data type known
not to have trap representations (either because the standard says so,
or because the compiler's documentation does), reading it is perfectly
safe; it has an unspecified value, but a valid one for the type.
Reading past the end of an array has undefined behavior, which is much
worse.

Ok, but I don't see how that relates to what I wrote. ...

You said '"reading uninitialized memory" is bad enough'; I was
explaining why that's not necessarily the case - at least not by
comparison with reading past the end of an array.
... I'm not claiming
that Valgrind warns about just /reading/ uninitialized memory, and I
agree that it's a harmless situation.

Reading past the end of the array is not harmless. It would be nice if
valgrind actually had the described option, enabling warnings about that
fact.

In my experience, valgrind *does* complain (loudly) about out-of-bounds
access, without any additional options.
A close inspection shows that there actually was no out-of-bounds access
in the no-if program, because the arrays were massively over-allocated.

The relevant portion of the allocation code is:

int size0fInt = sizeof(int64_t) * 8 - 1;
<...>
array2sort = (int64_t*)malloc(N0fItems * size0fInt);

Note that size0fInt is almost 8 times larger than needed.

Bart v Ingen Schenau
 
J

James Kuyper

.

In my experience, valgrind *does* complain (loudly) about out-of-bounds
access, without any additional options.
A close inspection shows that there actually was no out-of-bounds access
in the no-if program, because the arrays were massively over-allocated.

The relevant portion of the allocation code is:

int size0fInt = sizeof(int64_t) * 8 - 1;
<...>
array2sort = (int64_t*)malloc(N0fItems * size0fInt);

Note that size0fInt is almost 8 times larger than needed.

Note for those doing searches: size0fint is spelled with a zero, not an
Oh. In many fonts, it's hard to notice that.

OK - that makes me feel better about valgrind, a little worse about my
own ability to notice such things, and a lot worse about the competence
of the author of that code. The fact that you're the first person to
mention that problem, in a very long thread, makes me feel a little less
sheepish.

The size0fint calculation seems to have been copied over, without
understanding, from the calculation of size0fT1 in pseudoRNG() which was
a size in bits, rather than bytes. That calculation was based upon the
assumption that CHAR_BIT==8 is guaranteed - not an exactly uncommon
assumption. The -1 means that size0fT1 was a misnomer. In the original
context, it would have been clearer to write:

int size0fT1 = sizeof(uint64_t) * 8;
sign = (seed >> (size0fT1-1));

But it seems consistent with his other behavior that our micro-optimizer
was afraid that his compiler would fail to notice that size0fT1-1 was a
constant expression that could be lifted out of the loop. In the
calculation of size0fint, the -1 is just plain nonsense.
 
J

James Kuyper

.

In my experience, valgrind *does* complain (loudly) about out-of-bounds
access, without any additional options.
A close inspection shows that there actually was no out-of-bounds access
in the no-if program, because the arrays were massively over-allocated.

The relevant portion of the allocation code is:

int size0fInt = sizeof(int64_t) * 8 - 1;
<...>
array2sort = (int64_t*)malloc(N0fItems * size0fInt);

Note that size0fInt is almost 8 times larger than needed.

Note for those doing searches: size0fint is spelled with a zero, not an
Oh. In many fonts, it's hard to notice that.

OK - that makes me feel better about valgrind, a little worse about my
own ability to notice such things, and a lot worse about the competence
of the author of that code. The fact that you're the first person to
mention that problem, in a very long thread, makes me feel a little less
sheepish.

The size0fint calculation seems to have been copied over, without
understanding, from the calculation of size0fT1 in pseudoRNG() which was
a size in bits, rather than bytes. That calculation was based upon the
assumption that CHAR_BIT==8 is guaranteed - a fairly popular assumption,
and for practical purposes, one of the less dangerous incorrect
assumptions. The -1 means that size0fT1 was a misnomer. In the original
context, it would have been clearer to write:

int size0fT1 = sizeof(uint64_t) * 8;
sign = (seed >> (size0fT1-1));

But it seems consistent with his other behavior that our micro-optimizer
was afraid that his compiler would fail to notice that size0fT1-1 was a
constant expression that could be lifted out of the loop. In the
calculation of size0fint, the -1 is just plain nonsense.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,077
Messages
2,570,566
Members
47,202
Latest member
misc.

Latest Threads

Top