Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #4178 > unrolled thread
| Started by | Pushpa <pushpa@nospam.invalid> |
|---|---|
| First post | 2011-05-17 19:39 +0000 |
| Last post | 2011-05-19 09:12 -0600 |
| Articles | 20 on this page of 92 — 26 participants |
Back to article view | Back to comp.lang.c
Malloc Query Pushpa <pushpa@nospam.invalid> - 2011-05-17 19:39 +0000
Re: Malloc Query blp@cs.stanford.edu (Ben Pfaff) - 2011-05-17 12:55 -0700
Re: Malloc Query "BartC" <bc@freeuk.com> - 2011-05-18 12:05 +0100
Re: Malloc Query Pushpa <pushpa@nospam.invalid> - 2011-05-18 17:11 +0000
Re: Malloc Query "BartC" <bc@freeuk.com> - 2011-05-18 22:42 +0100
Re: Malloc Query Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-18 21:10 -0400
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-18 19:34 +0100
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-18 17:10 -0400
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-19 00:26 +0100
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-18 21:25 -0400
Re: Malloc Query James Kuyper <jameskuyper@verizon.net> - 2011-05-18 21:38 -0400
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-19 14:11 -0400
Re: Malloc Query James Kuyper <jameskuyper@verizon.net> - 2011-05-19 22:55 -0400
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-20 12:14 -0400
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-19 03:22 +0100
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-19 14:20 -0400
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-19 23:51 +0100
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-19 20:01 -0400
Re: Malloc Query luser- -droog <mijoryx@yahoo.com> - 2011-05-22 02:49 -0700
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-22 10:46 -0400
Re: Malloc Query Shao Miller <sha0.miller@gmail.com> - 2011-05-22 12:37 -0500
Re: Malloc Query Shao Miller <sha0.miller@gmail.com> - 2011-05-22 13:02 -0500
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-22 14:12 -0400
Re: Malloc Query Shao Miller <sha0.miller@gmail.com> - 2011-05-23 03:06 -0500
Re: Malloc Query luser- -droog <mijoryx@yahoo.com> - 2011-05-23 00:42 -0700
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-23 11:10 -0400
Re: Malloc Query Keith Thompson <kst-u@mib.org> - 2011-05-23 09:06 -0700
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-22 23:18 +0100
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-22 19:18 -0400
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-23 11:22 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-23 01:57 -0400
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-23 19:24 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-23 14:20 -0400
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-24 07:41 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-23 16:24 -0400
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-24 09:20 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-23 18:05 -0400
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-24 10:37 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-23 19:34 -0400
Re: Malloc Query "robertwessel2@yahoo.com" <robertwessel2@yahoo.com> - 2011-05-23 17:48 -0700
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-24 12:56 +1200
Re: Malloc Query James Kuyper <jameskuyper@verizon.net> - 2011-05-24 07:19 -0400
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-24 11:32 -0400
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-23 01:04 +0100
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-23 02:36 -0400
Re: Malloc Query luser- -droog <mijoryx@yahoo.com> - 2011-05-23 00:39 -0700
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-23 14:44 +0100
Re: Malloc Query Seebs <usenet-nospam@seebs.net> - 2011-05-23 15:16 +0000
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-23 11:41 -0400
Re: Malloc Query David Thompson <dave.thompson2@verizon.net> - 2011-06-01 16:33 -0400
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-19 18:34 -0400
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-20 02:36 +0100
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-20 12:26 -0400
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-20 23:32 +0100
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-20 21:17 -0400
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-21 14:30 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-21 11:13 -0400
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-22 08:50 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-21 20:03 -0400
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-22 13:23 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-22 10:01 -0400
Re: Malloc Query "io_x" <a@b.c.invalid> - 2011-05-26 08:12 +0200
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-26 19:16 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-26 15:03 -0400
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-27 09:16 +1200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-26 17:55 -0400
Re: Malloc Query "io_x" <a@b.c.invalid> - 2011-05-27 05:47 +0200
Re: Malloc Query Uncle Steve <stevet810@gmail.com> - 2011-05-26 15:02 -0400
Re: Malloc Query "BartC" <bc@freeuk.com> - 2011-05-18 22:31 +0100
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-18 23:37 +0100
Re: Malloc Query "BartC" <bc@freeuk.com> - 2011-05-19 01:50 +0100
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-19 02:50 +0100
Re: Malloc Query "BartC" <bc@freeuk.com> - 2011-05-19 12:14 +0100
Re: Malloc Query Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-05-19 15:10 +0100
Re: Malloc Query "BartC" <bc@freeuk.com> - 2011-05-19 15:48 +0100
Re: Malloc Query cri@tiac.net (Richard Harter) - 2011-05-18 19:31 +0000
Re: Malloc Query Ike Naar <ike@iceland.freeshell.org> - 2011-05-18 21:43 +0000
Re: Malloc Query "BartC" <bc@freeuk.com> - 2011-05-18 22:58 +0100
Re: Malloc Query Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-05-17 14:01 -0600
Re: Malloc Query Columbus sailed the ocean China Blue <chine.bleu@yahoo.com> - 2011-05-17 13:21 -0700
Re: Malloc Query BGB <cr88192@hotmail.com> - 2011-05-17 14:08 -0700
Re: Malloc Query Michael Press <rubrum@pacbell.net> - 2011-05-17 19:49 -0700
Re: Malloc Query Lauri Alanko <la@iki.fi> - 2011-05-18 00:50 +0000
Re: Malloc Query Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-17 21:21 -0400
Re: Malloc Query "io_x" <a@b.c.invalid> - 2011-05-18 19:31 +0200
Re: Malloc Query Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-05-18 21:36 +0000
Re: Malloc Query Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-05-18 21:26 -0400
Re: Malloc Query Tim Rentsch <txr@alumni.caltech.edu> - 2011-05-19 02:07 -0700
Re: Malloc Query Ian Collins <ian-news@hotmail.com> - 2011-05-19 21:13 +1200
Re: Malloc Query Nobody <nobody@nowhere.com> - 2011-05-18 07:08 +0100
Re: Malloc Query David Resnick <lndresnick@gmail.com> - 2011-05-19 07:51 -0700
Re: Malloc Query Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-05-19 09:12 -0600
Page 3 of 5 — ← Prev page 1 2 [3] 4 5 Next page →
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-05-24 12:56 +1200 |
| Message-ID | <940e1nFt2pU19@mid.individual.net> |
| In reply to | #4639 |
On 05/24/11 12:48 PM, robertwessel2@yahoo.com wrote: > On May 23, 2:41 pm, Ian Collins<ian-n...@hotmail.com> wrote: >> On 05/24/11 06:20 AM, Uncle Steve wrote: >> >>> On Mon, May 23, 2011 at 07:24:11PM +1200, Ian Collins wrote: >>>> On 05/23/11 05:57 PM, Uncle Steve wrote: >> >>>>> For my purposes, it is >>>>> sometimes nice to write a macro which uses conditionals to select a >>>>> particular code path through the macro. If the conditional can be >>>>> resolved at compile-time, the dead code branches in the macro are >>>>> pruned, saving space. A similarly structured function call won't be >>>>> optimized in this fashion unless (maybe) it is inlined. >> >>>> Why not? Whether the function is called or in line, the conditional >>>> compiles are still there. >> >>> A function is only inlined if it is defined in the same source file. >> >> Macros also have to be defined in the same compilation unit. >> >>> If you define a function in an external source file, it cannot be >>> inlined anywhere else unless the function is also defined in an >>> included header file. Doesn't everyone know this? >> >> I'm sure they do, what's your point? > > > Compilers that support link time code generation manage to inline > functions defined in different translation units all the time. I know, see one of my later posts. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-05-24 07:19 -0400 |
| Message-ID | <irg480$pfj$1@dont-email.me> |
| In reply to | #4571 |
On 05/23/2011 02:20 PM, Uncle Steve wrote: > On Mon, May 23, 2011 at 07:24:11PM +1200, Ian Collins wrote: >> On 05/23/11 05:57 PM, Uncle Steve wrote: ... >>> For my purposes, it is >>> sometimes nice to write a macro which uses conditionals to select a >>> particular code path through the macro. If the conditional can be >>> resolved at compile-time, the dead code branches in the macro are >>> pruned, saving space. A similarly structured function call won't be >>> optimized in this fashion unless (maybe) it is inlined. >> >> Why not? Whether the function is called or in line, the conditional >> compiles are still there. > > A function is only inlined if it is defined in the same source file. Not quite - it only has to be in the same translation unit. A translation unit consists of a given source file plus all of the other files merged into it by #include statements. The use of the function must also occur within the scope of the inline declaration, which basically means that the declaration should occur prior to the use. These requirements also apply to macros, though the scope rules are a bit different for them. > If you define a function in an external source file, it cannot be > inlined anywhere else unless the function is also defined in an > included header file. Doesn't everyone know this? If you replace your function-like macro, wherever it is that you have it defined, with an inline function definition in that same location, that function will be usable pretty much wherever the the macro was usable. It's probably feasible to come up with pathological contexts where a simple in-place replacement won't work, but such contexts are not the norm. ... >> Inlining is a very simple optimisation. You also overlook the opposite > > No it isn't. Perhaps not, but it's one that most popular modern compilers do routinely and very well; that's part of what makes them popular. >> optimisation - not inlining. There are situations where a smaller >> executable performs better (or even fit the target device!). The > > In <a8a6d14a9ed9b70-0c8ce@gmail.com> I wrote: > > Whether or not the code is inlined is going to depend more on > whether you are interested in performance or code size. > > Fitting code in some machines' L1 cache is harder with a lot of > gratuitous inlining, and you also pollute the l2 cache. Sometimes > this matters, and sometimes not. All highly dependent on the > specifics of the code and platform. Any decent compiler can be relied upon to take those issues into consideration when deciding whether or not to inline a function. This is something it can decide, independently of whether or not the function is declared inline. As far as actual inlining is concerned, the 'inline' keyword is only a hint, which a compiler is free to ignore; and it's perfectly legal for a compiler to decide to inline a function that is not declared 'inline', as long as doing so doesn't change the observable behavior. In fact, that was one of the arguments given against the introducing of the 'inline' keyword. Any static function written to meet the same special requirements that currently apply to 'inline' functions could already have been inlined, even if not so declared, so long as the compiler thought that doing so would be a good idea. Unless you know a lot more about the target platform than your compiler does, it's probably best to rely upon it to make inlining decisions. Defining a function (whether or not you use 'inline') gives it that option. Defining it as a function-like macro does not - it only allows inlining. Well, technically, I suppose a sufficiently sophisticated compiler could perform anti-inlining: recognizing a common code pattern, and replacing it wherever used with a call to a compiler-generated function definition. The fact that the common code was the result of a macro expansion would make it easier to recognize the feasibility of such an optimization. However, and it seems to me to be a harder optimization to perform than inlining, and I doubt that it is a common feature even of the most sophisticated compilers. -- James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Uncle Steve <stevet810@gmail.com> |
|---|---|
| Date | 2011-05-24 11:32 -0400 |
| Message-ID | <7bfe0ef149bdbdd-a0468@gmail.com> |
| In reply to | #4687 |
On Tue, May 24, 2011 at 07:19:28AM -0400, James Kuyper wrote: > On 05/23/2011 02:20 PM, Uncle Steve wrote: > > On Mon, May 23, 2011 at 07:24:11PM +1200, Ian Collins wrote: > >> On 05/23/11 05:57 PM, Uncle Steve wrote: > ... > >>> For my purposes, it is > >>> sometimes nice to write a macro which uses conditionals to select a > >>> particular code path through the macro. If the conditional can be > >>> resolved at compile-time, the dead code branches in the macro are > >>> pruned, saving space. A similarly structured function call won't be > >>> optimized in this fashion unless (maybe) it is inlined. > >> > >> Why not? Whether the function is called or in line, the conditional > >> compiles are still there. > > > > A function is only inlined if it is defined in the same source file. > > Not quite - it only has to be in the same translation unit. A > translation unit consists of a given source file plus all of the other > files merged into it by #include statements. The use of the function > must also occur within the scope of the inline declaration, which > basically means that the declaration should occur prior to the use. > These requirements also apply to macros, though the scope rules are a > bit different for them. Sorry, I'm not up on the technical nomenclature pertinent to compilers. I *meant* to say 'translation unit', but all my brain had was 'source file'. > > If you define a function in an external source file, it cannot be > > inlined anywhere else unless the function is also defined in an > > included header file. Doesn't everyone know this? > > If you replace your function-like macro, wherever it is that you have it > defined, with an inline function definition in that same location, that > function will be usable pretty much wherever the the macro was usable. > It's probably feasible to come up with pathological contexts where a > simple in-place replacement won't work, but such contexts are not the norm. Agreed. > >> Inlining is a very simple optimisation. You also overlook the opposite > > > > No it isn't. > > Perhaps not, but it's one that most popular modern compilers do > routinely and very well; that's part of what makes them popular. Inline functions are easy to use, but who can measure the performance advantage of inlining versus the code size tradeoff? I have no idea how to accurately measure and quantify the real advantages, which may be different for every architecture and application. I suspect the trend of blindly setting CFLAGS=-O9, which is not all that uncommon in makefiles, masks a profound ignorance of what really goes on in a running program. I also suspect that the complex interaction of compile and run-time factors defies simplistic optimization heuristics. > >> optimisation - not inlining. There are situations where a smaller > >> executable performs better (or even fit the target device!). The > > > > In <a8a6d14a9ed9b70-0c8ce@gmail.com> I wrote: > > > > Whether or not the code is inlined is going to depend more on > > whether you are interested in performance or code size. > > > > Fitting code in some machines' L1 cache is harder with a lot of > > gratuitous inlining, and you also pollute the l2 cache. Sometimes > > this matters, and sometimes not. All highly dependent on the > > specifics of the code and platform. > > Any decent compiler can be relied upon to take those issues into > consideration when deciding whether or not to inline a function. This is > something it can decide, independently of whether or not the function is > declared inline. As far as actual inlining is concerned, the 'inline' > keyword is only a hint, which a compiler is free to ignore; and it's > perfectly legal for a compiler to decide to inline a function that is > not declared 'inline', as long as doing so doesn't change the observable > behavior. In fact, that was one of the arguments given against the > introducing of the 'inline' keyword. Any static function written to meet > the same special requirements that currently apply to 'inline' functions > could already have been inlined, even if not so declared, so long as the > compiler thought that doing so would be a good idea. At least these compilers allow one to individually tune the optimization characteristic of the compilation process. If you don't want inlining, it's trivial to turn it off. > Unless you know a lot more about the target platform than your compiler > does, it's probably best to rely upon it to make inlining decisions. All things being equal, that is decent advice. > Defining a function (whether or not you use 'inline') gives it that > option. Defining it as a function-like macro does not - it only allows > inlining. Well, technically, I suppose a sufficiently sophisticated > compiler could perform anti-inlining: recognizing a common code pattern, > and replacing it wherever used with a call to a compiler-generated > function definition. The fact that the common code was the result of a > macro expansion would make it easier to recognize the feasibility of > such an optimization. However, and it seems to me to be a harder > optimization to perform than inlining, and I doubt that it is a common > feature even of the most sophisticated compilers. That kind of optimization would be the comp-sci equivalent of gilding the lily. Regards, Uncle Steve -- Should a professional politician be charged with molestation if he kisses babies while attending political rallies?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-05-23 01:04 +0100 |
| Message-ID | <0.dd74e92a138404c43559.20110523010437BST.874o4mnuy2.fsf@bsb.me.uk> |
| In reply to | #4534 |
Uncle Steve <stevet810@gmail.com> writes:
> On Sun, May 22, 2011 at 1u1:18:36PM +0100, Ben Bacarisse wrote:
>> Uncle Steve <stevet810@gmail.com> writes:
>>
>> > On Sun, May 22, 2011 at 02:49:51AM -0700, luser- -droog wrote:
>> >>
>> >> I've been using integer offsets instead of pointers a lot lately and
>> >> I think you might be better off using the array formula explicitly:
>> >>
>> >> #define arena_obj_addr(x, n) ((void *) (x->arena + n * x->obj_size))
>>
>> Everyone is taking chances here. The x and n should be in parentheses
>> so that the macro expands as expected. This is one reason why functions
>> are usually preferred.
I should also have said especially if the macro does not have an
ALL_CAPS name flagging it's macrosity.
> For a long time I've thought macros were preferable to functions for
> the reason that a function call has to save registers, stuff it's arguments on the
> stack, and so on. Macros should just fold into the program text,
They should, but the onus is on the programmer to make that reasonable
(and where there are side effects in the expressions used in the macro
"call" this may not be possible).
> but
> today inline functions are just as fast as macros.
Yes, using an inline function is better yet. You seemed dead against
them which is why I commented on the macro. Use a function and the
issue disappears.
> It has become a
> matter of preference. gcc even has the ability to use register
> calling conventions for function calls in some circumstances. The
> distinction between a macro and a function call is becoming moot.
I don't see how you can say that. The speed advantage that used to be
one of the main reasons to take the risk with macros has gone, but all
the potential bugs that function-like macros can hide are still there.
>> <snip>
>> > #define ARENA_TYPE struct foo
>
>> > struct arena_s {
>> > size_t arena_size;
>> > int free_list;
>> > size_t free;
>> > ARENA_TYPE * arena;
>> > };
>> >
>> > And your access macro becomes:
>> >
>> > #define arena_obj_addr(x, n) &x->arena[n]
>>
>> Here the [n] is OK, but why risk it with x? The (x) costs nothing and,
>> I think, saves time reading the macro since the reader does no have to
>> start worrying about what might be passed.
>
> No worries here. I've edited for brevity in posting, but I always
> protect macro arguments from side-effects these days. It doesn't look
> as clean and concise, which is why I omitted those statements from
> example code. No biggie.
OK. I'll try to remember to assume any errors in future code were added
for brevity and I'll save time by not commenting on it.
> In this newsgroup is it really preferable to see
>
> #define arena_object_addr(x, n) ({ \
> struct arena_s X = x; \
> int N = n; \
> *X->arena[N]; }) \
>
> for every dumb example that is posted?
The correct version of the macro is simpler than the one you seem to
think you'd write to make it safe. Why would you write the above (it's
wrong, so it's obviously not what you really use) instead of
*(x)->arena[n]
? Also, why would you use a non-standard feature when it's not needed? There
might be a reason to use ({...}) when a macro parameter is used more
than once that's not the case here. I suppose if you know you'll never
use another compiler, tying code to language extensions is not a problem.
> Possibly not if people can be
> reminded that all code posted in comp.lang.c is generally intended as
> an example.
One of the bug-bears of Usenet is "oh that's not the real code". This
translates to "you've just wasted your time". I'd vote for real code
(at the last code that's gone though a compiler) every time.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Uncle Steve <stevet810@gmail.com> |
|---|---|
| Date | 2011-05-23 02:36 -0400 |
| Message-ID | <ad38dbcccabfe98-406e6@gmail.com> |
| In reply to | #4536 |
On Mon, May 23, 2011 at 01:04:37AM +0100, Ben Bacarisse wrote:
> Uncle Steve <stevet810@gmail.com> writes:
>
> > On Sun, May 22, 2011 at 1u1:18:36PM +0100, Ben Bacarisse wrote:
> >> Uncle Steve <stevet810@gmail.com> writes:
> >>
> >> > On Sun, May 22, 2011 at 02:49:51AM -0700, luser- -droog wrote:
> >> >>
> >> >> I've been using integer offsets instead of pointers a lot lately and
> >> >> I think you might be better off using the array formula explicitly:
> >> >>
> >> >> #define arena_obj_addr(x, n) ((void *) (x->arena + n * x->obj_size))
> >>
> >> Everyone is taking chances here. The x and n should be in parentheses
> >> so that the macro expands as expected. This is one reason why functions
> >> are usually preferred.
>
> I should also have said especially if the macro does not have an
> ALL_CAPS name flagging it's macrosity.
But as some feel here, macrosity is a vanishing distinction. I use
all-caps macro names for constant expressions and the like. If I
think a macro will be more readable in lower-case, I'll do just that.
Shouted macro definitions interrupt the flow of source text when a
human is reading it, and I don't think I need that kind of distraction
in the code as much as some do.
> > For a long time I've thought macros were preferable to functions for
> > the reason that a function call has to save registers, stuff it's arguments on the
> > stack, and so on. Macros should just fold into the program text,
>
> They should, but the onus is on the programmer to make that reasonable
> (and where there are side effects in the expressions used in the macro
> "call" this may not be possible).
>
> > but
> > today inline functions are just as fast as macros.
>
> Yes, using an inline function is better yet. You seemed dead against
> them which is why I commented on the macro. Use a function and the
> issue disappears.
I'm not "dead against" function calls for simple things. I'm merely
predisposed against them.
> > It has become a
> > matter of preference. gcc even has the ability to use register
> > calling conventions for function calls in some circumstances. The
> > distinction between a macro and a function call is becoming moot.
>
> I don't see how you can say that. The speed advantage that used to be
> one of the main reasons to take the risk with macros has gone, but all
> the potential bugs that function-like macros can hide are still there.
Sorry, I should say 'moot' in consideration of the now historic
performance advantage of macros over function calls. In reality,
function calls /are/ slower than macro instances but the compiler
masks this when it inlines a function by omitting function preamble
and jinking the basic blocks of code to flow together as if they were
part of the immediate text.
> >> <snip>
> >> > #define ARENA_TYPE struct foo
> >
> >> > struct arena_s {
> >> > size_t arena_size;
> >> > int free_list;
> >> > size_t free;
> >> > ARENA_TYPE * arena;
> >> > };
> >> >
> >> > And your access macro becomes:
> >> >
> >> > #define arena_obj_addr(x, n) &x->arena[n]
> >>
> >> Here the [n] is OK, but why risk it with x? The (x) costs nothing and,
> >> I think, saves time reading the macro since the reader does no have to
> >> start worrying about what might be passed.
> >
> > No worries here. I've edited for brevity in posting, but I always
> > protect macro arguments from side-effects these days. It doesn't look
> > as clean and concise, which is why I omitted those statements from
> > example code. No biggie.
>
> OK. I'll try to remember to assume any errors in future code were added
> for brevity and I'll save time by not commenting on it.
Please do. I find it's the cut-and-paste-modify step that introduces
errors into program code more so than writing it in the first place.
> > In this newsgroup is it really preferable to see
> >
> > #define arena_object_addr(x, n) ({ \
> > struct arena_s X = x; \
> > int N = n; \
> > *X->arena[N]; }) \
> >
> > for every dumb example that is posted?
>
> The correct version of the macro is simpler than the one you seem to
> think you'd write to make it safe. Why would you write the above (it's
> wrong, so it's obviously not what you really use) instead of
>
> *(x)->arena[n]
That's only correct if the macro is a simple one-liner. If (x) is
used more than once and has side-effects, such as in (x++), you're
toast.
> ? Also, why would you use a non-standard feature when it's not needed? There
> might be a reason to use ({...}) when a macro parameter is used more
> than once that's not the case here. I suppose if you know you'll never
> use another compiler, tying code to language extensions is not a problem.
I'm a creature of habit, I guess. Note that while I didn't learn C
under gcc, it's about the only compiler I've used in the last
seventeen years. Consequently, avoiding its extensions is not an
automatic process. I'm making an effort to avoid non-portable code,
but it is slow going.
> > Possibly not if people can be
> > reminded that all code posted in comp.lang.c is generally intended as
> > an example.
>
> One of the bug-bears of Usenet is "oh that's not the real code". This
> translates to "you've just wasted your time". I'd vote for real code
> (at the last code that's gone though a compiler) every time.
I look at the majority of the example code posted in Usenet messages
as being contrived for the purposes of demonstration. When I was a
total noob, comp.sources.unix and a few others were places where real
code was made available to Usenet readers. So called real code is no
longer posted to newsgroups. I'm not ecstatic that my contrived
examples are not perfect, but the alternative is to post my 'real
code' and annoy people who would prefer the exemplar pared down to the
bare minimum.
The arena allocator I've been on about is instantiated as a .h file
and is over 500 lines of code at this time. It carries with it all
the 'baggage' of my development environment and would make the
discussion of its data structures and algorithm very awkward. A
reasonable compromise would be to ensure that posted code compiles
and works as expected, but even than that won't correct for all
possible errors: note that I buggered up the for() loop in the
arena_creat() function without triggering the error during testing.
I'll endeavor to post better code in subsequent messages, but it is
not always practical to test quick one-off constructs completely when
so many things compete for my (and your) time. I suppose I might
sound more intelligent and authoritative if my messages never
contained errors, but then I might never post at all if that were a
basic prerequisite for Usenet participation. Somewhere there is a
happy medium that will satisfy everyone here. I'll look more closely
for it. :)
Regards,
Uncle Steve
--
Should a professional politician be charged with molestation if he
kisses babies while attending political rallies?
[toc] | [prev] | [next] | [standalone]
| From | luser- -droog <mijoryx@yahoo.com> |
|---|---|
| Date | 2011-05-23 00:39 -0700 |
| Message-ID | <114c5ef1-0994-4946-bc01-7616bda5bb87@l26g2000yqm.googlegroups.com> |
| In reply to | #4545 |
On May 23, 1:36 am, Uncle Steve <stevet...@gmail.com> wrote: > On Mon, May 23, 2011 at 01:04:37AM +0100, Ben Bacarisse wrote: > > > One of the bug-bears of Usenet is "oh that's not the real code". This > > translates to "you've just wasted your time". I'd vote for real code > > (at the last code that's gone though a compiler) every time. > > I look at the majority of the example code posted in Usenet messages > as being contrived for the purposes of demonstration. When I was a > total noob, comp.sources.unix and a few others were places where real > code was made available to Usenet readers. So called real code is no > longer posted to newsgroups. I'm not ecstatic that my contrived > examples are not perfect, but the alternative is to post my 'real > code' and annoy people who would prefer the exemplar pared down to the > bare minimum. > Cast my vote for real code. Unless you're telling a story with little pieces of code. That's good too.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-05-23 14:44 +0100 |
| Message-ID | <0.b19c2eb4ac372a8142d2.20110523144418BST.87fwo5fs5p.fsf@bsb.me.uk> |
| In reply to | #4545 |
Uncle Steve <stevet810@gmail.com> writes:
> On Mon, May 23, 2011 at 01:04:37AM +0100, Ben Bacarisse wrote:
>> Uncle Steve <stevet810@gmail.com> writes:
>>
>> > On Sun, May 22, 2011 at 1u1:18:36PM +0100, Ben Bacarisse wrote:
>> >> Uncle Steve <stevet810@gmail.com> writes:
>> >>
>> >> > On Sun, May 22, 2011 at 02:49:51AM -0700, luser- -droog wrote:
>> >> >>
>> >> >> I've been using integer offsets instead of pointers a lot lately and
>> >> >> I think you might be better off using the array formula explicitly:
>> >> >>
>> >> >> #define arena_obj_addr(x, n) ((void *) (x->arena + n * x->obj_size))
>> >>
>> >> Everyone is taking chances here. The x and n should be in parentheses
>> >> so that the macro expands as expected. This is one reason why functions
>> >> are usually preferred.
>>
>> I should also have said especially if the macro does not have an
>> ALL_CAPS name flagging it's macrosity.
>
> But as some feel here, macrosity is a vanishing distinction.
There you go again. I won't say why not another time. Ian's also said
why the distinction is changing bit certainly not vanishing. Presumably
you don't accept the arguments, presumably because you never make a
mistake with your macros. Sorry, I just spotted "some". Who? You seem
to suggest you don't hold this view anymore.
> I use
> all-caps macro names for constant expressions and the like. If I
> think a macro will be more readable in lower-case, I'll do just that.
> Shouted macro definitions interrupt the flow of source text when a
> human is reading it, and I don't think I need that kind of distraction
> in the code as much as some do.
Ah. You code is for your eye only. Not only should it not be commented
on because you've edited for brevity, it should not be commented on for
readability or clarity because only you'll read it. I get it. Nothing
in you posted code should be commented on.
>> > For a long time I've thought macros were preferable to functions for
>> > the reason that a function call has to save registers, stuff it's arguments on the
>> > stack, and so on. Macros should just fold into the program text,
>>
>> They should, but the onus is on the programmer to make that reasonable
>> (and where there are side effects in the expressions used in the macro
>> "call" this may not be possible).
>>
>> > but
>> > today inline functions are just as fast as macros.
>>
>> Yes, using an inline function is better yet. You seemed dead against
>> them which is why I commented on the macro. Use a function and the
>> issue disappears.
>
> I'm not "dead against" function calls for simple things. I'm merely
> predisposed against them.
It no longer matters. Your code is for your eyes only and it does not
have any of the errors that plague other people when they use macros.
Any evidence to the contrary here is due to your thought posting code
edited versions for brevity.
>> > It has become a
>> > matter of preference. gcc even has the ability to use register
>> > calling conventions for function calls in some circumstances. The
>> > distinction between a macro and a function call is becoming moot.
>>
>> I don't see how you can say that. The speed advantage that used to be
>> one of the main reasons to take the risk with macros has gone, but all
>> the potential bugs that function-like macros can hide are still there.
>
> Sorry, I should say 'moot' in consideration of the now historic
> performance advantage of macros over function calls. In reality,
> function calls /are/ slower than macro instances but the compiler
> masks this when it inlines a function by omitting function preamble
> and jinking the basic blocks of code to flow together as if they were
> part of the immediate text.
I am very happy to have the slowness of something "masked" by the
compiler making if fast. In fact, I'd go so far as to say that it's not
slow anymore but you that's just my way of looking at it.
>> >> <snip>
>> >> > #define ARENA_TYPE struct foo
>> >
>> >> > struct arena_s {
>> >> > size_t arena_size;
>> >> > int free_list;
>> >> > size_t free;
>> >> > ARENA_TYPE * arena;
>> >> > };
>> >> >
>> >> > And your access macro becomes:
>> >> >
>> >> > #define arena_obj_addr(x, n) &x->arena[n]
>> >>
>> >> Here the [n] is OK, but why risk it with x? The (x) costs nothing and,
>> >> I think, saves time reading the macro since the reader does no have to
>> >> start worrying about what might be passed.
>> >
>> > No worries here. I've edited for brevity in posting, but I always
>> > protect macro arguments from side-effects these days. It doesn't look
>> > as clean and concise, which is why I omitted those statements from
>> > example code. No biggie.
>>
>> OK. I'll try to remember to assume any errors in future code were added
>> for brevity and I'll save time by not commenting on it.
>
> Please do. I find it's the cut-and-paste-modify step that introduces
> errors into program code more so than writing it in the first place.
>
>> > In this newsgroup is it really preferable to see
>> >
>> > #define arena_object_addr(x, n) ({ \
>> > struct arena_s X = x; \
>> > int N = n; \
>> > *X->arena[N]; }) \
>> >
>> > for every dumb example that is posted?
>>
>> The correct version of the macro is simpler than the one you seem to
>> think you'd write to make it safe. Why would you write the above (it's
>> wrong, so it's obviously not what you really use) instead of
>>
>> *(x)->arena[n]
>
> That's only correct if the macro is a simple one-liner. If (x) is
> used more than once and has side-effects, such as in (x++), you're
> toast.
You posted an incorrect one-liner. You then said it's OK because you
really use 4 lines and an non-C construct to do these things. The seems
daft to me. If the code is short (and this code was short) just write
the short version correctly. Errors happen, so more lines are often
worse than fewer. I know, errors don't happen in your real code so you
can be as verbose as you like, but for other people reading this shorter
macros are almost always better.
>> ? Also, why would you use a non-standard feature when it's not needed? There
>> might be a reason to use ({...}) when a macro parameter is used more
>> than once that's not the case here. I suppose if you know you'll never
>> use another compiler, tying code to language extensions is not a problem.
>
> I'm a creature of habit, I guess. Note that while I didn't learn C
> under gcc, it's about the only compiler I've used in the last
> seventeen years. Consequently, avoiding its extensions is not an
> automatic process. I'm making an effort to avoid non-portable code,
> but it is slow going.
gcc -std=c99 -pedantic if you want to avoid extensions. gcc -ansi
-pedantic is you want to avoid more non-portable features. I am sure
you know this, and using it in your real builds, but I comment in case
anyone else could use a reminder of how to make gcc limit itself to
standard C.
>> > Possibly not if people can be
>> > reminded that all code posted in comp.lang.c is generally intended as
>> > an example.
>>
>> One of the bug-bears of Usenet is "oh that's not the real code". This
>> translates to "you've just wasted your time". I'd vote for real code
>> (at the last code that's gone though a compiler) every time.
>
> I look at the majority of the example code posted in Usenet messages
> as being contrived for the purposes of demonstration.
Maybe, but it's real code in the sense that people want comments on it.
> When I was a
> total noob, comp.sources.unix and a few others were places where real
> code was made available to Usenet readers. So called real code is no
> longer posted to newsgroups. I'm not ecstatic that my contrived
> examples are not perfect, but the alternative is to post my 'real
> code' and annoy people who would prefer the exemplar pared down to the
> bare minimum.
Maybe just prefix the posting with "This is not real code. If there
are mistakes they are probably not there in the original so don't spend
time on the details. Stick to the gist of it."
> The arena allocator I've been on about is instantiated as a .h file
> and is over 500 lines of code at this time.
Hmmm.... I wonder if that affects the performance. Maybe not.
> It carries with it all
> the 'baggage' of my development environment and would make the
> discussion of its data structures and algorithm very awkward. A
> reasonable compromise would be to ensure that posted code compiles
> and works as expected, but even than that won't correct for all
> possible errors: note that I buggered up the for() loop in the
> arena_creat() function without triggering the error during testing.
>
> I'll endeavor to post better code in subsequent messages, but it is
> not always practical to test quick one-off constructs completely when
> so many things compete for my (and your) time. I suppose I might
> sound more intelligent and authoritative if my messages never
> contained errors, but then I might never post at all if that were a
> basic prerequisite for Usenet participation. Somewhere there is a
> happy medium that will satisfy everyone here. I'll look more closely
> for it. :)
Don't worry to much about it. No one else seems to mind, and I've got a
solution that works for me.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Seebs <usenet-nospam@seebs.net> |
|---|---|
| Date | 2011-05-23 15:16 +0000 |
| Message-ID | <slrnitku20.544.usenet-nospam@guild.seebs.net> |
| In reply to | #4561 |
On 2011-05-23, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote: > I am very happy to have the slowness of something "masked" by the > compiler making if fast. Beautiful phrasing. I think this gets to the heart of why good programmers measure before they optimize; our guesses as to what's fast and what's slow are often useless. I spent a while trying to improve the performance of the computational inner loop of a program, then thought to benchmark it a bit. It turns out the "computational inner loop" was under 10% of the run time*. ... oops. -s [*] Did you know that rendering antialiased lines on a 32-bit display is actually more computationally expensive than calculating their end points? Apparently, I didn't. -- Copyright 2011, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated! I am not speaking for my employer, although they do rent some of my opinions.
[toc] | [prev] | [next] | [standalone]
| From | Uncle Steve <stevet810@gmail.com> |
|---|---|
| Date | 2011-05-23 11:41 -0400 |
| Message-ID | <9a60f6fc5b1439a-7a342@gmail.com> |
| In reply to | #4561 |
On Mon, May 23, 2011 at 02:44:18PM +0100, Ben Bacarisse wrote:
> Uncle Steve <stevet810@gmail.com> writes:
>
> > On Mon, May 23, 2011 at 01:04:37AM +0100, Ben Bacarisse wrote:
> >> Uncle Steve <stevet810@gmail.com> writes:
> >>
> >> > On Sun, May 22, 2011 at 1u1:18:36PM +0100, Ben Bacarisse wrote:
> >> >> Uncle Steve <stevet810@gmail.com> writes:
> >> >>
> >> >> > On Sun, May 22, 2011 at 02:49:51AM -0700, luser- -droog wrote:
> >> >> >>
> >> >> >> I've been using integer offsets instead of pointers a lot lately and
> >> >> >> I think you might be better off using the array formula explicitly:
> >> >> >>
> >> >> >> #define arena_obj_addr(x, n) ((void *) (x->arena + n * x->obj_size))
> >> >>
> >> >> Everyone is taking chances here. The x and n should be in parentheses
> >> >> so that the macro expands as expected. This is one reason why functions
> >> >> are usually preferred.
> >>
> >> I should also have said especially if the macro does not have an
> >> ALL_CAPS name flagging it's macrosity.
> >
> > But as some feel here, macrosity is a vanishing distinction.
>
> There you go again. I won't say why not another time. Ian's also said
> why the distinction is changing bit certainly not vanishing. Presumably
> you don't accept the arguments, presumably because you never make a
> mistake with your macros. Sorry, I just spotted "some". Who? You seem
> to suggest you don't hold this view anymore.
Look. There are coding idioms that I use habitually; macros figure
prominently in specific roles. That's my coding standard, FWIW, and
as I've no supervisor dictating some other arbitrary standard, I am
perfectly happy with my style more or less as-is. My brain is not
composed of granite, so I am free to change my coding standards at
any time if I see a need to do so.
> > I use
> > all-caps macro names for constant expressions and the like. If I
> > think a macro will be more readable in lower-case, I'll do just that.
> > Shouted macro definitions interrupt the flow of source text when a
> > human is reading it, and I don't think I need that kind of distraction
> > in the code as much as some do.
>
> Ah. You code is for your eye only. Not only should it not be commented
> on because you've edited for brevity, it should not be commented on for
> readability or clarity because only you'll read it. I get it. Nothing
> in you posted code should be commented on.
See below.
> >> > For a long time I've thought macros were preferable to functions for
> >> > the reason that a function call has to save registers, stuff it's arguments on the
> >> > stack, and so on. Macros should just fold into the program text,
> >>
> >> They should, but the onus is on the programmer to make that reasonable
> >> (and where there are side effects in the expressions used in the macro
> >> "call" this may not be possible).
> >>
> >> > but
> >> > today inline functions are just as fast as macros.
> >>
> >> Yes, using an inline function is better yet. You seemed dead against
> >> them which is why I commented on the macro. Use a function and the
> >> issue disappears.
> >
> > I'm not "dead against" function calls for simple things. I'm merely
> > predisposed against them.
>
> It no longer matters. Your code is for your eyes only and it does not
> have any of the errors that plague other people when they use macros.
> Any evidence to the contrary here is due to your thought posting code
> edited versions for brevity.
...
> >> > It has become a
> >> > matter of preference. gcc even has the ability to use register
> >> > calling conventions for function calls in some circumstances. The
> >> > distinction between a macro and a function call is becoming moot.
> >>
> >> I don't see how you can say that. The speed advantage that used to be
> >> one of the main reasons to take the risk with macros has gone, but all
> >> the potential bugs that function-like macros can hide are still there.
> >
> > Sorry, I should say 'moot' in consideration of the now historic
> > performance advantage of macros over function calls. In reality,
> > function calls /are/ slower than macro instances but the compiler
> > masks this when it inlines a function by omitting function preamble
> > and jinking the basic blocks of code to flow together as if they were
> > part of the immediate text.
>
> I am very happy to have the slowness of something "masked" by the
> compiler making if fast. In fact, I'd go so far as to say that it's not
> slow anymore but you that's just my way of looking at it.
Right.
> >> >> <snip>
> >> >> > #define ARENA_TYPE struct foo
> >> >
> >> >> > struct arena_s {
> >> >> > size_t arena_size;
> >> >> > int free_list;
> >> >> > size_t free;
> >> >> > ARENA_TYPE * arena;
> >> >> > };
> >> >> >
> >> >> > And your access macro becomes:
> >> >> >
> >> >> > #define arena_obj_addr(x, n) &x->arena[n]
> >> >>
> >> >> Here the [n] is OK, but why risk it with x? The (x) costs nothing and,
> >> >> I think, saves time reading the macro since the reader does no have to
> >> >> start worrying about what might be passed.
> >> >
> >> > No worries here. I've edited for brevity in posting, but I always
> >> > protect macro arguments from side-effects these days. It doesn't look
> >> > as clean and concise, which is why I omitted those statements from
> >> > example code. No biggie.
> >>
> >> OK. I'll try to remember to assume any errors in future code were added
> >> for brevity and I'll save time by not commenting on it.
> >
> > Please do. I find it's the cut-and-paste-modify step that introduces
> > errors into program code more so than writing it in the first place.
> >
> >> > In this newsgroup is it really preferable to see
> >> >
> >> > #define arena_object_addr(x, n) ({ \
> >> > struct arena_s X = x; \
> >> > int N = n; \
> >> > *X->arena[N]; }) \
> >> >
> >> > for every dumb example that is posted?
> >>
> >> The correct version of the macro is simpler than the one you seem to
> >> think you'd write to make it safe. Why would you write the above (it's
> >> wrong, so it's obviously not what you really use) instead of
> >>
> >> *(x)->arena[n]
> >
> > That's only correct if the macro is a simple one-liner. If (x) is
> > used more than once and has side-effects, such as in (x++), you're
> > toast.
>
> You posted an incorrect one-liner. You then said it's OK because you
> really use 4 lines and an non-C construct to do these things. The seems
> daft to me. If the code is short (and this code was short) just write
> the short version correctly. Errors happen, so more lines are often
> worse than fewer. I know, errors don't happen in your real code so you
> can be as verbose as you like, but for other people reading this shorter
> macros are almost always better.
I didn't say it was ok that I made an error; I merely explained the
cause. Then you jumped on me for using a gccism. I've already spent
about four hours in the last twenty-four writing messages to this
newsgroup. How slowly should I write to Usenet?
> >> ? Also, why would you use a non-standard feature when it's not needed? There
> >> might be a reason to use ({...}) when a macro parameter is used more
> >> than once that's not the case here. I suppose if you know you'll never
> >> use another compiler, tying code to language extensions is not a problem.
> >
> > I'm a creature of habit, I guess. Note that while I didn't learn C
> > under gcc, it's about the only compiler I've used in the last
> > seventeen years. Consequently, avoiding its extensions is not an
> > automatic process. I'm making an effort to avoid non-portable code,
> > but it is slow going.
>
> gcc -std=c99 -pedantic if you want to avoid extensions. gcc -ansi
> -pedantic is you want to avoid more non-portable features. I am sure
> you know this, and using it in your real builds, but I comment in case
> anyone else could use a reminder of how to make gcc limit itself to
> standard C.
Actually, I'm not using that for my 'real' builds since I'm hardly
building anything at all right now. Instead I am writing and
designing. Trust me, I have enough details up in the air right now.
I don't even care if my code is compilable right at this moment as
designing it properly is a higher priority. If I had learned standard
C previously instead of gcc C, I wouldn't have this problem. So at
some point when the code base is stable, /then/ (and only then) will
I go through it to remove gccisms in the older stuff.
> >> > Possibly not if people can be
> >> > reminded that all code posted in comp.lang.c is generally intended as
> >> > an example.
> >>
> >> One of the bug-bears of Usenet is "oh that's not the real code". This
> >> translates to "you've just wasted your time". I'd vote for real code
> >> (at the last code that's gone though a compiler) every time.
> >
> > I look at the majority of the example code posted in Usenet messages
> > as being contrived for the purposes of demonstration.
>
> Maybe, but it's real code in the sense that people want comments on it.
True enough, but that also implies that people are doing just as I am,
and shortening their code to make their queries and examples more
concise.
> > When I was a
> > total noob, comp.sources.unix and a few others were places where real
> > code was made available to Usenet readers. So called real code is no
> > longer posted to newsgroups. I'm not ecstatic that my contrived
> > examples are not perfect, but the alternative is to post my 'real
> > code' and annoy people who would prefer the exemplar pared down to the
> > bare minimum.
>
> Maybe just prefix the posting with "This is not real code. If there
> are mistakes they are probably not there in the original so don't spend
> time on the details. Stick to the gist of it."
>
> > The arena allocator I've been on about is instantiated as a .h file
> > and is over 500 lines of code at this time.
>
> Hmmm.... I wonder if that affects the performance. Maybe not.
Quite a bit of it is documentation.
> > It carries with it all
> > the 'baggage' of my development environment and would make the
> > discussion of its data structures and algorithm very awkward. A
> > reasonable compromise would be to ensure that posted code compiles
> > and works as expected, but even than that won't correct for all
> > possible errors: note that I buggered up the for() loop in the
> > arena_creat() function without triggering the error during testing.
> >
> > I'll endeavor to post better code in subsequent messages, but it is
> > not always practical to test quick one-off constructs completely when
> > so many things compete for my (and your) time. I suppose I might
> > sound more intelligent and authoritative if my messages never
> > contained errors, but then I might never post at all if that were a
> > basic prerequisite for Usenet participation. Somewhere there is a
> > happy medium that will satisfy everyone here. I'll look more closely
> > for it. :)
>
> Don't worry to much about it. No one else seems to mind, and I've got a
> solution that works for me.
Ok, I won't.
Regards,
Uncle Steve
--
Should a professional politician be charged with molestation if he
kisses babies while attending political rallies?
[toc] | [prev] | [next] | [standalone]
| From | David Thompson <dave.thompson2@verizon.net> |
|---|---|
| Date | 2011-06-01 16:33 -0400 |
| Message-ID | <rt7du61rok03gsn7nmhik9hh3rh0edn5g8@4ax.com> |
| In reply to | #4561 |
On Mon, 23 May 2011 14:44:18 +0100, Ben Bacarisse <ben.usenet@bsb.me.uk> wrote: <snip: using GCCisms> > gcc -std=c99 -pedantic if you want to avoid extensions. gcc -ansi > -pedantic is you want to avoid more non-portable features. <snip> Other than those using (implementation-reserved) double-underscore, which are easy enough to search for (unless you construct them with token-pasting, and if so you deserve whatever problems you get). And things which are implementation-dependent (unspec or impl-def) in the standard. Those can be nonportable in general, but not from gcc specifically, and gcc doesn't flag them as such. (In some cases, the impl-dependent range or signedness of a type may trigger value-range, conversion-range, or unsigned-comparison warnings.)
[toc] | [prev] | [next] | [standalone]
| From | Uncle Steve <stevet810@gmail.com> |
|---|---|
| Date | 2011-05-19 18:34 -0400 |
| Message-ID | <fb81382c91724d0-17e8d@gmail.com> |
| In reply to | #4275 |
On Thu, May 19, 2011 at 03:22:18AM +0100, Ben Bacarisse wrote:
[snip]
Ok, here's a quick and dirty hack that measures a highly contrived
scenario. This code first allocates two arenas of different size, and
then ping-pongs the allocations between the two arenas for a defined
number of iterations. Then, I do more or less the same thing with
malloc.y
The preliminary results show that my special-purpose allocator is 2-3
times faster than glibc malloc. Not quite and order-of-magnitude
difference in performance (unless you think in base-2), but very
acceptable. In some programs there may be a larger difference in
performance becuase of reduceed memory fragmentation or reduced
overall memory use. I do not plan to isolate those factors at this
time to measure their effect.
Code is compiled with "gcc -O0 -o arena_test arena_test.c -lrt"
The test platform here is an Intel Atom netbook running at 1.333GHz,
1G RAM, OpenSuSE 11.4, libc-2.11.3, gcc 4.5.1 20101208.
Typical result:
[31/22:32] nb:pts/10 stevet ~/stuff/src/libs/tools/test: ./arena_test
Arena: Iterations: 100000; elapsed CPU time (msec): 39181
Malloc: Iterations: 100000; elapsed CPU time (msec): 107265
Code follows:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#define TEST_SIZE 1024 * 1024
#define ITERATIONS 100000
#define DIFFERENCE 5
struct arena_head_s {
int obj_size;
int arena_size;
unsigned char *
arena;
int free;
int free_list;
};
typedef struct arena_head_s arena_head;
#define arena_obj_addr(x, n) ((void *) &x->arena[n * x->obj_size])
arena_qa(arena_head *x)
{
int n;
n = x->free_list;
if(n != -1) {
x->free_list = *((int *) arena_obj_addr(x, n));
x->free--;
}
return(n);
}
void arena_free(arena_head *p, int n)
{
*((int *) arena_obj_addr(p, n)) = p->free_list;
p->free_list = n;
p->free++;
return;
}
arena_head * arena_creat(size_t s, int n)
{
arena_head * h;
int i;
h = malloc(sizeof(arena_head));
if(h == NULL) {
perror("malloc()");
exit(1);
}
h->obj_size = s;
h->arena_size = n;
h->free = n;
h->arena = malloc(s * n);
if(h->arena == NULL) {
perror("malloc()");
exit(1);
}
h->free_list = 0;
for(i = 0; i < n; i++)
*((int *) arena_obj_addr(h, i)) = i + 1;
*((int *) arena_obj_addr(h, i)) = -1;
return(h);
}
typedef unsigned long long int T64;
#define processcputime(p) \
{ \
T64 * t = p; \
struct timespec T; \
\
if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &T) == -1) { \
perror("clock_gettime()"); \
exit(1); \
} \
\
*t = ((T64)T.tv_sec) * 1000000LL + ((T64) T.tv_nsec / 1000); \
}
struct test_load_s {
int ref;
int data;
};
typedef struct test_load_s test_load;
void work(test_load *p)
{
if(!p) {
perror("null ptr");
exit(1);
}
p->ref++;
p->data = (int) p % 4 * rand();
return;
}
int main(int argc, char ** argv)
{
arena_head *h1, *h2;
T64 start, end;
int i, n;
test_load *p;
processcputime(&start);
h1 = arena_creat(sizeof(test_load), TEST_SIZE);
h2 = arena_creat(sizeof(test_load) + DIFFERENCE, TEST_SIZE);
if(!h1 || !h2) {
perror("arenas");
exit(1);
}
processcputime(&start);
for(i = 0; i < ITERATIONS; i++) {
n = arena_qa(h1);
if(n == -1) {
perror("Ooops.");
exit(1);
}
work(arena_obj_addr(h1, n));
n = arena_qa(h2);
if(n == -1) {
perror("Ooops 2.");
exit(1);
}
work(arena_obj_addr(h2, n));
}
processcputime(&end);
fprintf(stdout, "Arena: Iterations: %ld; elapsed CPU time (msec): %ld\n", ITERATIONS, (end - start));
processcputime(&start);
for(i = 0; i < ITERATIONS; i++) {
p = malloc(sizeof(test_load));
if(!p) {
perror("malloc()");
exit(1);
}
work(p);
p = malloc(sizeof(test_load) + DIFFERENCE);
if(!p) {
perror("malloc2()");
exit(1);
}
work(p);
}
processcputime(&end);
fprintf(stdout, "Malloc: Iterations: %ld; elapsed CPU time (msec): %ld\n", ITERATIONS, (end - start));
exit(0);
}
Regards,
Uncle Steve
--
Should a professional politician be charged with molestation if he
kisses babies while attending political rallies?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-05-20 02:36 +0100 |
| Message-ID | <0.59d068d4aa2044bdca20.20110520023648BST.87ei3uqhjj.fsf@bsb.me.uk> |
| In reply to | #4395 |
Uncle Steve <stevet810@gmail.com> writes: > On Thu, May 19, 2011 at 03:22:18AM +0100, Ben Bacarisse wrote: > [snip] > > > Ok, here's a quick and dirty hack that measures a highly contrived > scenario. This code first allocates two arenas of different size, and > then ping-pongs the allocations between the two arenas for a defined > number of iterations. Then, I do more or less the same thing with > malloc.y > > The preliminary results show that my special-purpose allocator is 2-3 > times faster than glibc malloc. Not quite and order-of-magnitude > difference in performance (unless you think in base-2), but very > acceptable. In some programs there may be a larger difference in > performance becuase of reduceed memory fragmentation or reduced > overall memory use. I do not plan to isolate those factors at this > time to measure their effect. You don't include the set-up time for the areans. That's fair if the pattern you expect to see is a very large number of allocations and a lot of re-use. If, however, new areans are needed in a long running program (because not all the memory is re-used) you'd have to include this cost. It makes a huge difference with the numbers you've picked: it halves the benefit on my system (3x vs 1.5x speed). I can reduce the effect of course just by increasing the number of timed iterations. For very small objects, with lots of optimisation and excluding the start-up costs I can get just over your order of magnitude speedup. That's a rather contrived scenario though. In particular, it is likely that the allocation code will not be able to be inlined (as I think it can be here). Thank you for providing something that can give real data, albeit for rather specific situations. FWIW I am on using an Intel(R) Core(TM)2 Duo CPU P8700 @ 2.53GHz. If I have time (looks unlikely) I'll plug it into a small binary tree program to see what happens when there is a little work being done too. <snip code> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Uncle Steve <stevet810@gmail.com> |
|---|---|
| Date | 2011-05-20 12:26 -0400 |
| Message-ID | <a8a6d14a9ed9b70-0c8ce@gmail.com> |
| In reply to | #4406 |
On Fri, May 20, 2011 at 02:36:48AM +0100, Ben Bacarisse wrote: > Uncle Steve <stevet810@gmail.com> writes: > > > On Thu, May 19, 2011 at 03:22:18AM +0100, Ben Bacarisse wrote: > > [snip] > > > > > > Ok, here's a quick and dirty hack that measures a highly contrived > > scenario. This code first allocates two arenas of different size, and > > then ping-pongs the allocations between the two arenas for a defined > > number of iterations. Then, I do more or less the same thing with > > malloc.y > > > > The preliminary results show that my special-purpose allocator is 2-3 > > times faster than glibc malloc. Not quite and order-of-magnitude > > difference in performance (unless you think in base-2), but very > > acceptable. In some programs there may be a larger difference in > > performance becuase of reduceed memory fragmentation or reduced > > overall memory use. I do not plan to isolate those factors at this > > time to measure their effect. > > You don't include the set-up time for the areans. That's fair if the > pattern you expect to see is a very large number of allocations and a > lot of re-use. If, however, new areans are needed in a long running > program (because not all the memory is re-used) you'd have to include > this cost. True enough, but it's not wrong to charge the set-up cost to program initialization mainly because the arena allocator is mainly suitable for those situations where there will be a lot of re-use. Malloc may also have set-up costs as well that are hidden in program initialization, but that will depend on the implementation. > It makes a huge difference with the numbers you've picked: it halves the > benefit on my system (3x vs 1.5x speed). I can reduce the effect of > course just by increasing the number of timed iterations. For very > small objects, with lots of optimisation and excluding the start-up > costs I can get just over your order of magnitude speedup. That's a > rather contrived scenario though. In particular, it is likely that the > allocation code will not be able to be inlined (as I think it can be > here). Whether or not the code is inlined is going to depend more on whether you are interested in performance or code size. Of course it is trivial to force the allocation routine inline -- just make it a macro. Whether that makes any sort of difference at all is highly application specific, and is bound to be of less importance than the difference in algorithm design. > Thank you for providing something that can give real data, albeit for > rather specific situations. FWIW I am on using an Intel(R) Core(TM)2 > Duo CPU P8700 @ 2.53GHz. I'm mildly curious as to the numbers you got, would you mind posting them? > If I have time (looks unlikely) I'll plug it into a small binary tree > program to see what happens when there is a little work being done too. Coincidentally, a binary tree algorithm is just the application that I envisioned as suitable for use with this allocator. At some point I probably will be measuring its performance, so I'll have a better idea of whats going on in that case when I get to it. Regards, Uncle Steve -- Should a professional politician be charged with molestation if he kisses babies while attending political rallies?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-05-20 23:32 +0100 |
| Message-ID | <0.0445c33066fc3df6c97c.20110520233246BST.87ei3tove9.fsf@bsb.me.uk> |
| In reply to | #4436 |
Uncle Steve <stevet810@gmail.com> writes: <snip> > I'm mildly curious as to the numbers you got, would you mind posting > them? Not at all. Exactly as per your compile but I added more iterations just in case I was not getting good times: Arena: Iterations: 1000000; elapsed CPU time (msec): 36109 Malloc: Iterations: 1000000; elapsed CPU time (msec): 107952 If I add in the set-up costs: Arena: Iterations: 1000000; elapsed CPU time (msec): 70330 Malloc: Iterations: 1000000; elapsed CPU time (msec): 107935 Base case again but with maximum optimisation turned on (-O3): Arena: Iterations: 1000000; elapsed CPU time (msec): 12303 Malloc: Iterations: 1000000; elapsed CPU time (msec): 104033 and the same but, again, with the set-up time included: Arena: Iterations: 1000000; elapsed CPU time (msec): 39187 Malloc: Iterations: 1000000; elapsed CPU time (msec): 102874 (gcc version 4.4.3) <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Uncle Steve <stevet810@gmail.com> |
|---|---|
| Date | 2011-05-20 21:17 -0400 |
| Message-ID | <674e95901d3dba6-6851e@gmail.com> |
| In reply to | #4464 |
On Fri, May 20, 2011 at 11:32:46PM +0100, Ben Bacarisse wrote: > Uncle Steve <stevet810@gmail.com> writes: > > <snip> > > I'm mildly curious as to the numbers you got, would you mind posting > > them? > > Not at all. Exactly as per your compile but I added more iterations > just in case I was not getting good times: > > Arena: Iterations: 1000000; elapsed CPU time (msec): 36109 > Malloc: Iterations: 1000000; elapsed CPU time (msec): 107952 > > If I add in the set-up costs: > > Arena: Iterations: 1000000; elapsed CPU time (msec): 70330 > Malloc: Iterations: 1000000; elapsed CPU time (msec): 107935 > > Base case again but with maximum optimisation turned on (-O3): > > Arena: Iterations: 1000000; elapsed CPU time (msec): 12303 > Malloc: Iterations: 1000000; elapsed CPU time (msec): 104033 > > and the same but, again, with the set-up time included: > > Arena: Iterations: 1000000; elapsed CPU time (msec): 39187 > Malloc: Iterations: 1000000; elapsed CPU time (msec): 102874 Funny. Your numbers are almost exactly 10x better than mine on the netbook. But at -O3, I get: Arena: Iterations: 100000; elapsed CPU time (msec): 28540 Malloc: Iterations: 100000; elapsed CPU time (msec): 97913 Which is 2.5 (*10) poorer than your results. I don't know what that actually signifies, but it's kind of interesting. Regards, Uncle Steve -- Should a professional politician be charged with molestation if he kisses babies while attending political rallies?
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-05-21 14:30 +1200 |
| Message-ID | <93omefF1bbU15@mid.individual.net> |
| In reply to | #4395 |
On 05/20/11 10:34 AM, Uncle Steve wrote:
A couple of comments on the code:
<snip>
> arena_head * arena_creat(size_t s, int n)
> {
> arena_head * h;
> int i;
>
> h = malloc(sizeof(arena_head));
> if(h == NULL) {
> perror("malloc()");
> exit(1);
> }
>
> h->obj_size = s;
> h->arena_size = n;
> h->free = n;
>
> h->arena = malloc(s * n);
> if(h->arena == NULL) {
> perror("malloc()");
> exit(1);
> }
>
> h->free_list = 0;
>
> for(i = 0; i< n; i++)
> *((int *) arena_obj_addr(h, i)) = i + 1;
>
> *((int *) arena_obj_addr(h, i)) = -1;
This writes past the end of the allocated block.
> return(h);
> }
>
>
> typedef unsigned long long int T64;
>
> #define processcputime(p) \
Why go the the trouble of declaring this as a messy macro?
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Uncle Steve <stevet810@gmail.com> |
|---|---|
| Date | 2011-05-21 11:13 -0400 |
| Message-ID | <b5cf4d9e084fa3f-1edbb@gmail.com> |
| In reply to | #4484 |
On Sat, May 21, 2011 at 02:30:39PM +1200, Ian Collins wrote:
> On 05/20/11 10:34 AM, Uncle Steve wrote:
>
> A couple of comments on the code:
>
> <snip>
>
> >arena_head * arena_creat(size_t s, int n)
> >{
> > arena_head * h;
> > int i;
> >
> > h = malloc(sizeof(arena_head));
> > if(h == NULL) {
> > perror("malloc()");
> > exit(1);
> > }
> >
> > h->obj_size = s;
> > h->arena_size = n;
> > h->free = n;
> >
> > h->arena = malloc(s * n);
> > if(h->arena == NULL) {
> > perror("malloc()");
> > exit(1);
> > }
> >
> > h->free_list = 0;
> >
> > for(i = 0; i< n; i++)
> > *((int *) arena_obj_addr(h, i)) = i + 1;
> >
> > *((int *) arena_obj_addr(h, i)) = -1;
>
> This writes past the end of the allocated block.
Ha, you're right. The original code this is based on doesn't have
that problem. The for(;;) comparison should be i < (n - 1). Since I
wrote it in less than an hour, there ought to be several good bugs in
there.
> > return(h);
> >}
> >
> >
> >typedef unsigned long long int T64;
> >
> >#define processcputime(p)
> >\
>
> Why go the the trouble of declaring this as a messy macro?
I'm not all that interested in nanosecond resolution for timing
things, so I scaled the resolution down to microseconds and turned it
into a 64-bit quantity so arithmetic calculations would be more
convenient. I suppose it could be a function call, but inline it
probably generates ten or so instructions. Insulating the actual
system function call also makes porting a little easier.
Regards,
Uncle Steve
--
Should a professional politician be charged with molestation if he
kisses babies while attending political rallies?
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-05-22 08:50 +1200 |
| Message-ID | <93qmsmF1bbU17@mid.individual.net> |
| In reply to | #4494 |
On 05/22/11 03:13 AM, Uncle Steve wrote: > On Sat, May 21, 2011 at 02:30:39PM +1200, Ian Collins wrote: >> On 05/20/11 10:34 AM, Uncle Steve wrote: >>> >>> typedef unsigned long long int T64; >>> >>> #define processcputime(p) >>> \ >> >> Why go the the trouble of declaring this as a messy macro? > > I'm not all that interested in nanosecond resolution for timing > things, so I scaled the resolution down to microseconds and turned it > into a 64-bit quantity so arithmetic calculations would be more > convenient. I suppose it could be a function call, but inline it > probably generates ten or so instructions. No more or less than an inlined function call. > Insulating the actual > system function call also makes porting a little easier. But doing so in a macro makes it harder! -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Uncle Steve <stevet810@gmail.com> |
|---|---|
| Date | 2011-05-21 20:03 -0400 |
| Message-ID | <e3fe3d2160801c5-77e43@gmail.com> |
| In reply to | #4501 |
On Sun, May 22, 2011 at 08:50:26AM +1200, Ian Collins wrote: > On 05/22/11 03:13 AM, Uncle Steve wrote: > >On Sat, May 21, 2011 at 02:30:39PM +1200, Ian Collins wrote: > >>On 05/20/11 10:34 AM, Uncle Steve wrote: > >>> > >>>typedef unsigned long long int T64; > >>> > >>>#define processcputime(p) > >>>\ > >> > >>Why go the the trouble of declaring this as a messy macro? > > > >I'm not all that interested in nanosecond resolution for timing > >things, so I scaled the resolution down to microseconds and turned it > >into a 64-bit quantity so arithmetic calculations would be more > >convenient. I suppose it could be a function call, but inline it > >probably generates ten or so instructions. > > No more or less than an inlined function call. Right, so what's the problem? > >Insulating the actual > >system function call also makes porting a little easier. > > But doing so in a macro makes it harder! Not really. Maybe what I don't get is what you mean by 'harder'. Is 'harder' some ineffable quality that in a more robust age would serve to differentiate the men from the boys? I like to think so, but I don't think it's a popular view. Regards, Uncle Steve -- Should a professional politician be charged with molestation if he kisses babies while attending political rallies?
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-05-22 13:23 +1200 |
| Message-ID | <93r6sfF1bbU20@mid.individual.net> |
| In reply to | #4504 |
On 05/22/11 12:03 PM, Uncle Steve wrote: > On Sun, May 22, 2011 at 08:50:26AM +1200, Ian Collins wrote: >> On 05/22/11 03:13 AM, Uncle Steve wrote: >>> On Sat, May 21, 2011 at 02:30:39PM +1200, Ian Collins wrote: >>>> On 05/20/11 10:34 AM, Uncle Steve wrote: >>>>> >>>>> typedef unsigned long long int T64; >>>>> >>>>> #define processcputime(p) >>>>> \ >>>> >>>> Why go the the trouble of declaring this as a messy macro? >>> >>> I'm not all that interested in nanosecond resolution for timing >>> things, so I scaled the resolution down to microseconds and turned it >>> into a 64-bit quantity so arithmetic calculations would be more >>> convenient. I suppose it could be a function call, but inline it >>> probably generates ten or so instructions. >> >> No more or less than an inlined function call. > > Right, so what's the problem? Using a macro where a function would do. >>> Insulating the actual >>> system function call also makes porting a little easier. >> >> But doing so in a macro makes it harder! > > Not really. Maybe what I don't get is what you mean by 'harder'. > Is 'harder' some ineffable quality that in a more robust age would > serve to differentiate the men from the boys? I like to think so, but > I don't think it's a popular view. Well there's more to type (all those pesky line continuation characters to line up), no way to step in if you have a bug you can't easily diagnose and stylistic limits imposed by a macro. The function would be more concise if it could return its result. -- Ian Collins
[toc] | [prev] | [next] | [standalone]
Page 3 of 5 — ← Prev page 1 2 [3] 4 5 Next page →
Back to top | Article view | comp.lang.c
csiph-web