Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #16842 > unrolled thread

a = b or memset/cpy?

Started bynroberts <roberts.noah@gmail.com>
First post2012-02-07 09:02 -0800
Last post2012-02-14 08:30 -0500
Articles 19 — 12 participants

Back to article view | Back to comp.lang.c


Contents

  a = b or memset/cpy? nroberts <roberts.noah@gmail.com> - 2012-02-07 09:02 -0800
    Re: a = b or memset/cpy? Jens Gustedt <jens.gustedt@loria.fr> - 2012-02-07 18:41 +0100
      Re: a = b or memset/cpy? James Kuyper <jameskuyper@verizon.net> - 2012-02-07 13:40 -0500
        Re: a = b or memset/cpy? Jens Gustedt <jens.gustedt@loria.fr> - 2012-02-07 20:09 +0100
        Re: a = b or memset/cpy? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-07 11:37 -0800
          Re: a = b or memset/cpy? Shao Miller <sha0.miller@gmail.com> - 2012-02-07 18:35 -0500
      Re: a = b or memset/cpy? nroberts <roberts.noah@gmail.com> - 2012-02-07 11:07 -0800
        Re: a = b or memset/cpy? blp@cs.stanford.edu (Ben Pfaff) - 2012-02-07 11:14 -0800
          Re: a = b or memset/cpy? nroberts <roberts.noah@gmail.com> - 2012-02-07 11:41 -0800
        Re: a = b or memset/cpy? Shao Miller <sha0.miller@gmail.com> - 2012-02-07 18:39 -0500
    Re: a = b or memset/cpy? "Scott Fluhrer" <sfluhrer@ix.netcom.com> - 2012-02-07 14:14 -0500
    Re: a = b or memset/cpy? Shao Miller <sha0.miller@gmail.com> - 2012-02-07 18:58 -0500
      Re: a = b or memset/cpy? Shao Miller <sha0.miller@gmail.com> - 2012-02-07 21:58 -0500
      Re: a = b or memset/cpy? Jens Gustedt <jens.gustedt@loria.fr> - 2012-02-09 21:34 +0100
    Re: a = b or memset/cpy? Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-07 20:34 -0500
    Re: a = b or memset/cpy? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-02-08 18:43 +0000
    Re: a = b or memset/cpy? jgk@panix.com (Joe keane) - 2012-02-08 20:05 +0000
      Re: a = b or memset/cpy? Ian Collins <ian-news@hotmail.com> - 2012-02-09 09:18 +1300
    Re: a = b or memset/cpy? Tim Prince <tim@nospamcomputer.org> - 2012-02-14 08:30 -0500

#16842 — a = b or memset/cpy?

Fromnroberts <roberts.noah@gmail.com>
Date2012-02-07 09:02 -0800
Subjecta = b or memset/cpy?
Message-ID<abb85a15-f68c-4e2f-8985-fe8b4945aca0@t8g2000yqg.googlegroups.com>
memset and memcpy are turning up in profiles a lot.  I'd like to speed
things up a bit.

Sometimes it is clear that using = to initialize a local would be
better than memset.  I might not gain anything, but at least there's a
chance.

However, can I gain performance improvements when zeroing out say some
global element in an array like so:

typedef struct x { int var0; char var1[20]; } X;

X gX[30];

void f(int slot)
{
  X init = {0};

  gX[slot] = init;

  ...
}

vs.
void f(int slot)
{
  memset(&gX[slot], 0, sizeof(X));

  ...
}

Normally I wouldn't look for a micro-optimization like this but I'm
kind of stuck with the parameters I'm given.

[toc] | [next] | [standalone]


#16851

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-02-07 18:41 +0100
Message-ID<4F316233.2040208@loria.fr>
In reply to#16842
Am 02/07/2012 06:02 PM, schrieb nroberts:
> X gX[30];
> 
> void f(int slot)
> {
>   X init = {0};
> 
>   gX[slot] = init;
> 
>   ...
> }

make it

X const init = { 0 };

or even better use a compound literal

gX[slot] = (X const){ 0 };

> Normally I wouldn't look for a micro-optimization like this but I'm
> kind of stuck with the parameters I'm given.

On any decent compiler the assignment version should not be worse that
the memset version, because the compiler must be able to see that it
is an object only filled with 0.

On the other hand the assignment version *may* be better, when the
compiler can do a data flow analysis that shows e.g that part of what
you initialize is overwritten before being read.

So I'd always prefer the assigment version.

Jens

[toc] | [prev] | [next] | [standalone]


#16855

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-07 13:40 -0500
Message-ID<4F31703B.1070003@verizon.net>
In reply to#16851
On 02/07/2012 12:41 PM, Jens Gustedt wrote:
> Am 02/07/2012 06:02 PM, schrieb nroberts:
>> X gX[30];
>>
>> void f(int slot)
>> {
>>   X init = {0};
>>
>>   gX[slot] = init;
>>
>>   ...
>> }
> 
> make it
> 
> X const init = { 0 };
> 
> or even better use a compound literal
> 
> gX[slot] = (X const){ 0 };
> 
>> Normally I wouldn't look for a micro-optimization like this but I'm
>> kind of stuck with the parameters I'm given.
> 
> On any decent compiler the assignment version should not be worse that

This is initialization, not assignment.

> the memset version, because the compiler must be able to see that it
> is an object only filled with 0.

I've used a compiler which, given the following code:

	double array[10][1354][3] = {0};

generated the equivalent of the following:

	array[0][0][0] = 0;
	array[0][0][1] = 0;
etc.
The resulting executable was noticeably larger that I had expected it to
be. I was a little annoyed when I figured out what was going on. I
changed it to use memset(), and got a lot smaller, and executed somewhat
faster, too. The support person I talked with said that my use of {0}
was unreasonable, not their compiler's code generation.

[toc] | [prev] | [next] | [standalone]


#16856

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-02-07 20:09 +0100
Message-ID<4F3176ED.3080503@loria.fr>
In reply to#16855
Am 02/07/2012 07:40 PM, schrieb James Kuyper:
> On 02/07/2012 12:41 PM, Jens Gustedt wrote:
>> On any decent compiler the assignment version should not be worse that
> 
> This is initialization, not assignment.

No, you are mistaken. The relevant part is assignment to gX[slot]. The
other part is just initialization of a const. In particular the
initialization of the const qualified compound literal can be done at
compile time if the compiler decides that it is beneficial (as if it
where declared as a static variable).

>> the memset version, because the compiler must be able to see that it
>> is an object only filled with 0.
> 
> I've used a compiler which, given the following code:
> 
> 	double array[10][1354][3] = {0};
> 
> generated the equivalent of the following:
> 
> 	array[0][0][0] = 0;
> 	array[0][0][1] = 0;
> etc.
> The resulting executable was noticeably larger that I had expected it to
> be. I was a little annoyed when I figured out what was going on. I
> changed it to use memset(), and got a lot smaller, and executed somewhat
> faster, too. The support person I talked with said that my use of {0}
> was unreasonable, not their compiler's code generation.

How long ago and what compiler was that? My observation over the last
years is that a compiler like gcc is capable of optimizing assignments
to struct fields or different array members as if all of these were
different variables.

(and double may be special, setting all bytes to 0 and initializing
with 0 must not necessarily be the same thing.)

Jens

[toc] | [prev] | [next] | [standalone]


#16860

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-07 11:37 -0800
Message-ID<61a3bf72-f6b4-4d97-9961-9ac73b903e95@y10g2000vbn.googlegroups.com>
In reply to#16855
On Feb 7, 6:40 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> The support person I talked with said that my use of {0}
> was unreasonable, not their compiler's code generation.
>
Well what can he say? He can't patch the compiler to replace a long
intialisation with a call to memset().

[toc] | [prev] | [next] | [standalone]


#16889

FromShao Miller <sha0.miller@gmail.com>
Date2012-02-07 18:35 -0500
Message-ID<jgsca8$i3n$1@dont-email.me>
In reply to#16860
On 2/7/2012 14:37, Malcolm McLean wrote:
> On Feb 7, 6:40 pm, James Kuyper<jameskuy...@verizon.net>  wrote:
>> The support person I talked with said that my use of {0}
>> was unreasonable, not their compiler's code generation.
>>
> Well what can he say? He can't patch the compiler to replace a long
> intialisation with a call to memset().
>

Call == LOL.  Good one. :)

And the support person cannot patch the compiler to replace a 'struct' 
object assignment with a call to 'memcpy' either, presumably.

I've used a Microsoft C implementation which actually will give you a 
linker error if you do:

   void func(void) {
       int array[42] = { 0 };
       return;
     }

and choose not to link with the standard library...  It complains about 
a missing 'memset' symbol...

[toc] | [prev] | [next] | [standalone]


#16857

Fromnroberts <roberts.noah@gmail.com>
Date2012-02-07 11:07 -0800
Message-ID<7466b5d5-56f7-4ab0-a918-ffbc0fd64b76@dp8g2000vbb.googlegroups.com>
In reply to#16851
On Feb 7, 9:41 am, Jens Gustedt <jens.gust...@loria.fr> wrote:
> Am 02/07/2012 06:02 PM, schrieb nroberts:
>
> > X gX[30];
>
> > void f(int slot)
> > {
> >   X init = {0};
>
> >   gX[slot] = init;
>
> >   ...
> > }
>
> make it
>
> X const init = { 0 };
>
> or even better use a compound literal
>
> gX[slot] = (X const){ 0 };
>
> > Normally I wouldn't look for a micro-optimization like this but I'm
> > kind of stuck with the parameters I'm given.
>
> On any decent compiler the assignment version should not be worse that
> the memset version, because the compiler must be able to see that it
> is an object only filled with 0.
>
> On the other hand the assignment version *may* be better, when the
> compiler can do a data flow analysis that shows e.g that part of what
> you initialize is overwritten before being read.
>
> So I'd always prefer the assigment version.
>
> Jens

LOL!

Nevermind.  I'm not allowed to use this language feature.  It's too
"complex".  People won't know what it does.

Not the '=' operator... Initializing a structure to all 0 with = {0}.

:/

I keep running into bosses like this.  Is this normal in the
programming field or am I just incredibly unlucky?

[toc] | [prev] | [next] | [standalone]


#16859

Fromblp@cs.stanford.edu (Ben Pfaff)
Date2012-02-07 11:14 -0800
Message-ID<87mx8uzc9m.fsf@blp.benpfaff.org>
In reply to#16857
nroberts <roberts.noah@gmail.com> writes:

> Nevermind.  I'm not allowed to use this language feature.  It's too
> "complex".  People won't know what it does.
>
> Not the '=' operator... Initializing a structure to all 0 with = {0}.

Look on the bright side: on that basis, you should have no
trouble avoiding C++ entirely at that workplace.
-- 
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}

[toc] | [prev] | [next] | [standalone]


#16861

Fromnroberts <roberts.noah@gmail.com>
Date2012-02-07 11:41 -0800
Message-ID<598fce10-2246-47d0-af45-71cdbc4835cb@o13g2000vbf.googlegroups.com>
In reply to#16859
On Feb 7, 11:14 am, b...@cs.stanford.edu (Ben Pfaff) wrote:
> nroberts <roberts.n...@gmail.com> writes:
> > Nevermind.  I'm not allowed to use this language feature.  It's too
> > "complex".  People won't know what it does.
>
> > Not the '=' operator... Initializing a structure to all 0 with = {0}.
>
> Look on the bright side: on that basis, you should have no
> trouble avoiding C++ entirely at that workplace.

I don't consider that a good thing.

[toc] | [prev] | [next] | [standalone]


#16891

FromShao Miller <sha0.miller@gmail.com>
Date2012-02-07 18:39 -0500
Message-ID<jgsch3$i3n$2@dont-email.me>
In reply to#16857
On 2/7/2012 14:07, nroberts wrote:
> LOL!
>
> Nevermind.  I'm not allowed to use this language feature.  It's too
> "complex".  People won't know what it does.
>
> Not the '=' operator... Initializing a structure to all 0 with = {0}.
>
> :/
>
> I keep running into bosses like this.  Is this normal in the
> programming field or am I just incredibly unlucky?

That feature has been around since C89/C90.  Perhaps you can find a 
clever way for your boss to find that out without losing face or without 
regretting disallowing its use.

[toc] | [prev] | [next] | [standalone]


#16858

From"Scott Fluhrer" <sfluhrer@ix.netcom.com>
Date2012-02-07 14:14 -0500
Message-ID<1328642200.7550@rcdn-nntpcache-2>
In reply to#16842
"nroberts" <roberts.noah@gmail.com> wrote in message 
news:abb85a15-f68c-4e2f-8985-fe8b4945aca0@t8g2000yqg.googlegroups.com...
> memset and memcpy are turning up in profiles a lot.  I'd like to speed
> things up a bit.
>
> Sometimes it is clear that using = to initialize a local would be
> better than memset.  I might not gain anything, but at least there's a
> chance.

Without any measurements, no one can say for certain.  However, my guess is 
that it wouldn't matter, because the overhead isn't particulary how you're 
writing the data, but the fact that you are writing data (and causing cache 
misses, which are what is expensive).

What might be a fruitful avenue to explore would be to ask yourself "why do 
I need to initialize them so often, and is there a way I can reduce the 
number of times I need to do it?"

-- 
poncho

[toc] | [prev] | [next] | [standalone]


#16893

FromShao Miller <sha0.miller@gmail.com>
Date2012-02-07 18:58 -0500
Message-ID<jgsdla$ol5$1@dont-email.me>
In reply to#16842
On 2/7/2012 12:02, nroberts wrote:
> memset and memcpy are turning up in profiles a lot.  I'd like to speed
> things up a bit.
>

You might find that the implementation actually translates a '= { 0 
};'-style initializer into a call to 'memset'.  An experiment might 
reveal whether or not that's the case.

> Sometimes it is clear that using = to initialize a local would be
> better than memset.  I might not gain anything, but at least there's a
> chance.
>

I'm not sure how you could gain anything unless the call to 'memset' 
actually translates differently than a '= { 0 };'-style initializer.

Did you know that after all subobjects that are explicitly initialized 
(by the initializer-list) have been so, the rest are initialized to what 
they would have been had the object been declared with 'static' storage 
duration?  The whole containing object is thus "touched."

> However, can I gain performance improvements when zeroing out say some
> global element in an array like so:
>
> typedef struct x { int var0; char var1[20]; } X;
>
> X gX[30];
>
> void f(int slot)
> {
>    X init = {0};
>
>    gX[slot] = init;
>
>    ...
> }
>
> vs.
> void f(int slot)
> {
>    memset(&gX[slot], 0, sizeof(X));
>
>    ...
> }
>

Well these aren't the same.  The former initializes all sub-objects to 
the "zeroey" values that would initialize a 'static'-storage-duration 
object having the same type as the sub-object and having no explicit 
initializer.

The latter fills the object with bytes with the 'unsigned char' value 
'0', which is all-bits-zero.

In your example, the 'struct' type 'X' has an 'int' member.  The object 
representation of an 'int' can have padding bits that can be used any 
way the implementation pleases.

If filling the padding bits with zeroes results in a trap representation 
for an 'int', then you might be in for a surprise.

There are similar concerns for other types, including pointers, where a 
null pointer value might not be all-bits-zero.

That is why I believe some people consider a '= { 0 };'-style 
initializer to be more portable than 'memset'.  If portability isn't a 
concern, oh well.

> Normally I wouldn't look for a micro-optimization like this but I'm
> kind of stuck with the parameters I'm given.

Optmizing and making portable might not always be compatible.  If you 
have a particular set of implementations as your target(s), there might 
be "compiler intrinsics" that you can use which are 
implementation-defined extensions to C that could offer you speed 
advantages.

For example, some Microsoft compilers offer '__movsd':

   http://msdn.microsoft.com/en-us/library/9d196b9h.aspx

[toc] | [prev] | [next] | [standalone]


#16905

FromShao Miller <sha0.miller@gmail.com>
Date2012-02-07 21:58 -0500
Message-ID<jgso8d$ass$1@dont-email.me>
In reply to#16893
On 2/7/2012 18:58, Shao Miller wrote:
>>
>> typedef struct x { int var0; char var1[20]; } X;
>>
>> X gX[30];
>>
>> void f(int slot)
>> {
>> X init = {0};
>>
>> gX[slot] = init;
>>
>> ...
>> }
>>
>> vs.
>> void f(int slot)
>> {
>> memset(&gX[slot], 0, sizeof(X));
>>
>> ...
>> }
>>
>
> Well these aren't the same. The former initializes all sub-objects to
> the "zeroey" values that would initialize a 'static'-storage-duration
> object having the same type as the sub-object and having no explicit
> initializer.
>
> The latter fills the object with bytes with the 'unsigned char' value
> '0', which is all-bits-zero.
>
> In your example, the 'struct' type 'X' has an 'int' member. The object
> representation of an 'int' can have padding bits that can be used any
> way the implementation pleases.
>
> If filling the padding bits with zeroes results in a trap representation
> for an 'int', then you might be in for a surprise.
>

Ben Bacarisse proved in another thread that my claim for a potential 
surprise is false; there is no potential for all-zero-bits in an 
integer's object representation to be a trap representation.  Sorry 
about that!

> There are similar concerns for other types, including pointers, where a
> null pointer value might not be all-bits-zero.
>

Still applies for other things, like pointers. :)

[toc] | [prev] | [next] | [standalone]


#16993

FromJens Gustedt <jens.gustedt@loria.fr>
Date2012-02-09 21:34 +0100
Message-ID<4F342DBE.9030600@loria.fr>
In reply to#16893
Am 02/08/2012 12:58 AM, schrieb Shao Miller:
> On 2/7/2012 12:02, nroberts wrote:

> I'm not sure how you could gain anything unless the call to 'memset'
> actually translates differently than a '= { 0 };'-style initializer.

The gain is in the knowledge of the optimizer. If you have a memset
initialization it is difficult (but not impossible) for the optimizer
to keep track of initializations. If it knows of initializations and
it encounters an assignment of a field of the struct before it is ever
read, the optimizer is allowed to omit the initialization. Modern
optimizers can be quite good in tracking individual struct or array
members.

Jens

[toc] | [prev] | [next] | [standalone]


#16902

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-07 20:34 -0500
Message-ID<jgsjeb$ncg$1@dont-email.me>
In reply to#16842
On 2/7/2012 12:02 PM, nroberts wrote:
> memset and memcpy are turning up in profiles a lot.  I'd like to speed
> things up a bit.
>
> Sometimes it is clear that using = to initialize a local would be
> better than memset.  I might not gain anything, but at least there's a
> chance.
>
> However, can I gain performance improvements when zeroing out say some
> global element in an array like so:
>
> typedef struct x { int var0; char var1[20]; } X;
>
> X gX[30];
>
> void f(int slot)
> {
>    X init = {0};
>
>    gX[slot] = init;
>
>    ...
> }
>
> vs.
> void f(int slot)
> {
>    memset(&gX[slot], 0, sizeof(X));
>
>    ...
> }

     The official answer is: The definition of the C language says
nothing about which constructs are faster or slower than others.

     That said, I would expect memset() to be faster, usually, if
the wind is not unfavorable and the Moon is in the right quarter.
Argument: In the assignment version, the code must allocate the auto
variable `init', zero it, and then copy all those zeroes to `gX[slot]';
on the face of it, this sounds like more work than just zeroing
`gX[slot]' to begin with.

     It is just possible that a very smart compiler could (1) realize
that the `init' variable is not actually necessary, (2) decide to
clear `gX[slot]' directly instead of clearing `init' and copying,
and (3) clear `gX[slot]' more efficiently than memset() can, perhaps
with in-line code.  My suspicion, though, is that a compiler smart
enough for (1,2,3) would not at the same time be so dumb as to
implement memset() with an actual call to an actual external function;
you'd need a strange combination of brilliance and stupidity to get
an advantage for initialize-and-copy.

     ... and, of course, measurement is the only way to be sure.

> Normally I wouldn't look for a micro-optimization like this but I'm
> kind of stuck with the parameters I'm given.

     My prejudice (and I admit it's something of a prejudice) would be
to take a hard look at those memset() and memcpy() calls, with a view
toward eliminating at least some of them -- if you can eliminate a
call you get an infinite speedup, as opposed to a mere hundredfold!
Making copies of bits you've already computed usually doesn't advance
the state of the computation very much; making many duplicates of a
single byte is also not usually a great addition to the program's
"knowledge."  There are, of course, exceptions: qsort() just rearranges
bits you already own, for example, but can be useful nonetheless.
Still, if memset() and memcpy() are dominating the run time, it seems
likely that there may be a lot of needless setting and copying going
on.  See what you can jettison.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#16932

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2012-02-08 18:43 +0000
Message-ID<slrnjj5gj4.1ls.grahn+nntp@frailea.sa.invalid>
In reply to#16842
On Tue, 2012-02-07, nroberts wrote:
> memset and memcpy are turning up in profiles a lot.  I'd like to speed
> things up a bit.
>
> Sometimes it is clear that using = to initialize a local would be
> better than memset.  I might not gain anything, but at least there's a
> chance.

For copying with memcpy(), I much prefer assignment since it doesn't
bypass the type system, and is more readable.

I won't comment on the memset() part.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#16935

Fromjgk@panix.com (Joe keane)
Date2012-02-08 20:05 +0000
Message-ID<jgukhf$199$1@reader1.panix.com>
In reply to#16842
In article <abb85a15-f68c-4e2f-8985-fe8b4945aca0@t8g2000yqg.googlegroups.com>,
nroberts  <roberts.noah@gmail.com> wrote:
>memset and memcpy are turning up in profiles a lot.

Indeed.

>Sometimes it is clear that using = to initialize a local would be
>better than memset.

It's a shame if you call a function with a size parameter, when in fact
the size is a compile-time constant.  You also probably know a bit about
alignment, whereas those guys have to assume the worst.

>I might not gain anything, but at least there's a chance.

Please to use real data!  'gprof' is very good at this.  It works [so
far as i have seen] on stdlib calls as well as your functions.

It can tell you where you're getting killed by function call overhead,
and where the copy is taking a long time, such that you may go to more
length to avoid it.  It can also (by switching back to a function) tell
you where your 'optimization' does nothing except increase code size.

[toc] | [prev] | [next] | [standalone]


#16937

FromIan Collins <ian-news@hotmail.com>
Date2012-02-09 09:18 +1300
Message-ID<9pg3liFom1U3@mid.individual.net>
In reply to#16935
On 02/ 9/12 09:05 AM, Joe keane wrote:
> In article<abb85a15-f68c-4e2f-8985-fe8b4945aca0@t8g2000yqg.googlegroups.com>,
> nroberts<roberts.noah@gmail.com>  wrote:
>> memset and memcpy are turning up in profiles a lot.
>
> Indeed.
>
>> Sometimes it is clear that using = to initialize a local would be
>> better than memset.
>
> It's a shame if you call a function with a size parameter, when in fact
> the size is a compile-time constant.  You also probably know a bit about
> alignment, whereas those guys have to assume the worst.

A decent compiler will inline the call to memset() in this case, so 
there is no call overhead.  Whether the inline memset() is faster or 
slower than an assignment to a const initialiser is something the OP 
would have to measure.

>> I might not gain anything, but at least there's a chance.
>
> Please to use real data!  'gprof' is very good at this.  It works [so
> far as i have seen] on stdlib calls as well as your functions.

Assuming the OP uses GNU tools...

> It can tell you where you're getting killed by function call overhead,
> and where the copy is taking a long time, such that you may go to more
> length to avoid it.  It can also (by switching back to a function) tell
> you where your 'optimization' does nothing except increase code size.

Assuming there is a function call...

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#17306

FromTim Prince <tim@nospamcomputer.org>
Date2012-02-14 08:30 -0500
Message-ID<9pv5vrF9vrU1@mid.individual.net>
In reply to#16842
On 02/07/2012 12:02 PM, nroberts wrote:
> memset and memcpy are turning up in profiles a lot.  I'd like to speed
> things up a bit.
>
> Sometimes it is clear that using = to initialize a local would be
> better than memset.  I might not gain anything, but at least there's a
> chance.
>
> However, can I gain performance improvements when zeroing out say some
> global element in an array like so:
>
> typedef struct x { int var0; char var1[20]; } X;
>
> X gX[30];
>
> void f(int slot)
> {
>    X init = {0};
>
>    gX[slot] = init;
>
>    ...
> }
>
> vs.
> void f(int slot)
> {
>    memset(&gX[slot], 0, sizeof(X));
>
>    ...
> }
>
> Normally I wouldn't look for a micro-optimization like this but I'm
> kind of stuck with the parameters I'm given.

Certain compilers make such transformations automatically; for only 30 
elements, presumably with reasonable alignment (with compiler able to 
see it via in-lining), in-line code may be best, but compilers may 
prefer memset() to reduce code size.  It may make a difference when one 
or the other applies a cache bypass (IA nontemporal) when the move is 
seen as large enough to need it, which 30 elements clearly is not.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web