gcc initialization better or extra line of execution

A

anish singh

So here is the problem:

Progarm 'A'
main()
{
char array[128] = {0};
memcpy(array, "testing", strlen("testing"));
}


Progarm 'B'
main()
{
char array[128];
memcpy(array, "testing", strlen("testing"));
array[strlen("testing")] = '\0';
}

Which one is better program?Definition of better: A program is better if it has less code size and executes in less cycle.

Argument 1: Program 'B' is better as it doesn't have to initialize the whole array and just need to append '\0' at the end which is just one more cycle.

Please answer this question with concrete data in any architecture i.e. ARM, x86 or anything which is available to you.

Please use disassembly to explain your point w.r.t. cycles or code size.Strictly guess is not allowed.
 
A

anish singh

So here is the problem:
Progarm 'A'

char array[128] = {0};
memcpy(array, "testing", strlen("testing"));

Progarm 'B'

char array[128];
memcpy(array, "testing", strlen("testing"));
array[strlen("testing")] = '\0';

Which one is better program?Definition of better: A program is better if it has less code size and executes in less cycle.
Argument 1: Program 'B' is better as it doesn't have to initialize the whole array and just need to append '\0' at the end which is just one more cycle.
Please answer this question with concrete data in any architecture i.e. ARM, x86 or anything which is available to you.
Please use disassembly to explain your point w.r.t. cycles or code size.Strictly guess is not allowed.





You'll learn much more if you do your own homework.

Einstein, well what suggests that this this a homework?Mind explaining the answer than answering in this way thinking that you know the answer or instilling a feeling in everyone that you know something.
 
K

Keith Thompson

anish singh said:
So here is the problem:

Progarm 'A'
main()
{
char array[128] = {0};
memcpy(array, "testing", strlen("testing"));
}


Progarm 'B'
main()
{
char array[128];
memcpy(array, "testing", strlen("testing"));
array[strlen("testing")] = '\0';
}

Which one is better program?Definition of better: A program is better
if it has less code size and executes in less cycle.

Argument 1: Program 'B' is better as it doesn't have to initialize the
whole array and just need to append '\0' at the end which is just one
more cycle.

Please answer this question with concrete data in any architecture
i.e. ARM, x86 or anything which is available to you.

Please use disassembly to explain your point w.r.t. cycles or code
size.Strictly guess is not allowed.

Please provide your instructor's e-mail address so we can submit our
answers directly. We'll be glad to mention your name if you like.
 
J

Jorgen Grahn

So here is the problem:

Progarm 'A'
main()
{
char array[128] = {0};
memcpy(array, "testing", strlen("testing"));
}


Progarm 'B'
main()
{
char array[128];
memcpy(array, "testing", strlen("testing"));
array[strlen("testing")] = '\0';
}

Which one is better program?Definition of better: A program is
better if it has less code size and executes in less cycle.

(Unusual definition, by the way.)

I'd expect both of them to optimize into nothing, since they don't do
anything! (Except return 0 from main, or whatever it means to leave
out the return -- I'm confused by the archaic C style.)

/Jorgen
 
X

Xavier Roche

Le 09/11/2013 08:47, anish singh a écrit :
Which one is better program?

Both are lame. Use strcpy() [or better, strlcpy(), but this is another
story] or only one memcpy() [which will be inlined with some luck].
 
M

Malcolm McLean

Einstein, well what suggests that this this a homework?Mind explaining
the answer than answering in this way thinking that you know the answer
or instilling a feeling in everyone that you know something.

Please answer this question with concrete data in any architecture i.e. ARM, x86 or anything which is available to you.

Please use disassembly to explain your point w.r.t. cycles or code size.Strictly guess is not allowed.
 
J

James Kuyper

Einstein, well what suggests that this this a homework? ...

Many things, thought the last line is the most revealing. "Not allowed"
is something teachers say to students; it's not something that normally
occurs in a request by a novice for information from an expert.
... Mind
explaining the answer than answering in this way thinking that you
know the answer or instilling a feeling in everyone that you know
something.

Most people who post here regularly (even including some of the trolls)
are competent to answer this question. Those who've failed to answer
your question haven't been doing so because of ignorance.
 
B

Ben Bacarisse

anish singh said:
So here is the problem:

Progarm 'A'
main()
{
char array[128] = {0};
memcpy(array, "testing", strlen("testing"));
}


Progarm 'B'
main()
{
char array[128];
memcpy(array, "testing", strlen("testing"));
array[strlen("testing")] = '\0';
}

Which one is better program?Definition of better: A program is better
if it has less code size and executes in less cycle.

A much less contentious question would be which one has less code and
executes in fewer cycles? Calling this criterion "better" is just
crazy.

Both programs have some archaic features (missing #include, implicit int
for main) but, more importantly, both miss the optimal way to do the
copy:

memcpy(array, "testing", sizeof "testing");
Argument 1: Program 'B' is better as it doesn't have to initialize the
whole array and just need to append '\0' at the end which is just one
more cycle.

You can't know that. Not only might strlen be called again (there are
some very dumb compilers out there) but you can't tell how many
instructions the final line takes, let along how many cycles it will
take to execute them.

<snip>
 
G

glen herrmannsfeldt

anish singh said:
So here is the problem:
Progarm 'A'
main()
{
char array[128] = {0};
memcpy(array, "testing", strlen("testing"));
}
Progarm 'B'
main()
{
char array[128];
memcpy(array, "testing", strlen("testing"));
array[strlen("testing")] = '\0';
}
Which one is better program?Definition of better: A program is
better if it has less code size and executes in less cycle.

This problem does look suspiciously like homework. If it isn't,
then you can explain why this matters. How about:

Progarm 'C'
main()
{
char array[128];
memcpy(array, "testing", sizeof("testing"));
}

or

Progarm 'D'
main()
{
char array[128];
strcpy(array, "testing");
}

There are some cases in embedded systems where every byte of code and
every cycle of execution matter, but they are rare and getting rarer.

There are some cases in embedded systems where every byte of code and
cycle of execution matter. Now, consider:

Progarm 'E'
main()
{
static char array[128]="testing";
}

Note that there are no exectuable statements, so it should take no
bytes of code and no cycles to execute.

Finally, I offer:

Progarm 'F'
main()
{
char array[128];
strncpy(array, "testing", sizeof(a));
}

The problem with the question, besides sounding suspiciously like
homework, is what it doesn't ask. There are many other ways that may
be better, so there is no reason to find the advantages of those two.

Also, some systems will generate inline code, others an actual
function call. That might change with optimization level, too.

And, finally, the two differ in the contents of the array, such that one
needs the exact context to know.

-- glen
 
S

Seebs

So here is the problem:

Yes, yes it is.
Progarm 'A'
main()
{
char array[128] = {0};
memcpy(array, "testing", strlen("testing"));
}

This program is wrong.
Progarm 'B'
main()
{
char array[128];
memcpy(array, "testing", strlen("testing"));
array[strlen("testing")] = '\0';
}

This program is also wrong, and frankly sort of excessively so.
Which one is better program?

They're both bad.

{
char array[128] = "testing";
}
Definition of better: A program is better if it has less code size and executes in less cycle.

No, *this* is the problem.

Your definition of "better" is wrong. Wrong in many ways.

1. You are failing to consider the case where you have a tradeoff
between code size and cycle count.
2. You might want to distinguish between "cycles" and "time", because they
are not equivalent.
3. This is a stupid definition of "better" for 99% of all purposes,
because the dominating factor in nearly all programming issues is
bugs, and that means that clarity beats everything.
4. If you are even remotely thinking about code size and cycle count
for trivial crap like this, you are doing it at the expense of thinking
clearly about higher-level considerations like algorithm design, which
can usually result in order-of-magnitude improvements in program
performance.
Argument 1: Program 'B' is better as it doesn't have to initialize the whole array and just need to append '\0' at the end which is just one more cycle.

Depends a lot. Does the compiler notice that you're calling strlen() on a
string literal? If not, you've got a function call and a loop happening
there, which can eat up a lot of cycles, and many CPUs will have cheap
ways to zero out an array.
Please answer this question with concrete data in any architecture i.e. ARM, x86 or anything which is available to you.
Why?

Please use disassembly to explain your point w.r.t. cycles or code size.
No.

Strictly guess is not allowed.

Knowing what the issues are without reference to the assembly output is
not "guessing".

-s
 
S

Seebs

Einstein, well what suggests that this this a homework?

Lots of things. But your attitude here is sure not changing that
perception at all.

As an obvious answer, though: There is no likely non-homework reason to
ask such a question.

-s
 
S

Seebs

Both programs have some archaic features (missing #include, implicit int
for main) but, more importantly, both miss the optimal way to do the
copy:
memcpy(array, "testing", sizeof "testing");

Huh. I'd never done that, so it wouldn't have occurred to me, but
string literals get the desired behavior from sizeof, don't they.

-s
 
S

Seebs

Reminds me of the time, years ago, I spent a morning cleaning up and
optimizing (making 'better') a small batch utility program. I was so
proud of myself. That is until I had to explain to my boss how I spent
my morning.

The program essentially paused a process and waited 10 seconds before
starting it up again. Now it did exactly the same thing, but it did it
much faster than before. <g>

I once, for April Fools, wrote an article showing in great detail how to
optimize some heavily-hit code in the Darwin kernel using the Altivec vector
extensions.

It was the idle loop.

-s
 
K

Keith Thompson

glen herrmannsfeldt said:
Finally, I offer:

Progarm 'F'
main()
{
char array[128];
strncpy(array, "testing", sizeof(a));
}

How is the strncpy call better than

strcpy(array, "testing");

? Using strncpy rather than strcpy gives no added safety *in this case*
because it's obvious that the array is more than big enough. And if it
weren't obvious, you'd risk leaving the target array unterminated (i.e.,
not containing a string). Furthermore, since we're talking about speed,
strncpy() is likely to be very slightly more expensive than an
equivalent strcpy(), since (a) it has to check against both the length
and the null terminator in the source, and (b) it (probably
unnecessarily) pads the target with nulls.

[...]
 
K

Keith Thompson

anish singh said:
Einstein, well what suggests that this this a homework?Mind explaining
the answer than answering in this way thinking that you know the
answer or instilling a feeling in everyone that you know something.

You seem to be offended at the suggestion that your question is
homework, but I can't help noticing that you haven't actually said that
it isn't.

So, is this homework?
 
S

Seebs

You seem to be offended at the suggestion that your question is
homework, but I can't help noticing that you haven't actually said that
it isn't.

I think that was actually a pretty clear indication that it was.

Although that thing starting "Mind explaining..." is a beautiful hunk of
verbiage, and I genuinely can't tell whether it's intended to be one or
two sentences, or how the clauses are attached.

-s
 
G

glen herrmannsfeldt

(snip, I wrote)
Finally, I offer:
Progarm 'F'
main()
{
char array[128];
strncpy(array, "testing", sizeof(a));
}
How is the strncpy call better than
strcpy(array, "testing");
? Using strncpy rather than strcpy gives no added safety *in this case*
because it's obvious that the array is more than big enough. And if it
weren't obvious, you'd risk leaving the target array unterminated (i.e.,
not containing a string). Furthermore, since we're talking about speed,
strncpy() is likely to be very slightly more expensive than an
equivalent strcpy(), since (a) it has to check against both the length
and the null terminator in the source, and (b) it (probably
unnecessarily) pads the target with nulls.

The point of the question is comparing different ways. And note that the
OP didn't say what the rest of the array should contain. Initializing
to zero and then memcpy() zeros the rest of the array, the OP's other
choice does not.

Do any systems zero initialized auto arrays by copying from an array
constant? (In the general case of auto array it has to copy from
somewhere, but it might specialize for zero.

The favorite string initialization (to all the same character) for S/360
(and, I believe, successors) is to store into the first byte with MVI
(move immediate, one byte) and then MVC (move characters) one to the
right.

MVI ARRAY,0
MVC ARRAY+1(L'ARRAY-1),ARRAY

In C terms:

array[0]=0;
memcpy(array+1,array,sizeof(array)-1);

except that memcpy() is undefined for the overlapping case.
(The OP asked for some specific examples, so now he has one.)
I believe some processor special case this operation.

-- glen
 
B

Ben Bacarisse

Seebs said:
Huh. I'd never done that, so it wouldn't have occurred to me, but
string literals get the desired behavior from sizeof, don't they.

Well I don't recall ever writing it (or seeing it for that matter) "in
the wild", but I do recall writing a macro to do literal token matching
in a buffer that used

strncmp(buffer, "token", sizeof "token" - 1)

where, of course, the result from sizeof was not exactly right.
 
A

anish singh

So here is the problem:



Yes, yes it is.


Progarm 'A'

char array[128] = {0};
memcpy(array, "testing", strlen("testing"));



This program is wrong.
Yes, I know it is wrong.This was not written to compile
but more of a pseudocode.
Progarm 'B'

char array[128];
memcpy(array, "testing", strlen("testing"));
array[strlen("testing")] = '\0';



This program is also wrong, and frankly sort of excessively so. Yes, I know that.


Which one is better program?



They're both bad.
Yes, as this is a silly question.
{

char array[128] = "testing";

}


Definition of better: A program is better if it has less code size and executes in less cycle.



No, *this* is the problem.
Yes, this is the problem.This question gets its origin from a silly
code review where the reviewer commented what i wrote as argument 1
in my original question.
Your definition of "better" is wrong. Wrong in many ways.
Yes, as the code in question is not posted here but rather the pseudocode
to get the comments from the experts present here.
1. You are failing to consider the case where you have a tradeoff

between code size and cycle count.
This is the best part till now which just confirms my understanding.
2. You might want to distinguish between "cycles" and "time", because they

are not equivalent. Yes.

3. This is a stupid definition of "better" for 99% of all purposes,

because the dominating factor in nearly all programming issues is

bugs, and that means that clarity beats everything.
Yes,I told that this question stemmed from a silly code review by a so-called
expert senior.
4. If you are even remotely thinking about code size and cycle count

for trivial crap like this, you are doing it at the expense of thinking

clearly about higher-level considerations like algorithm design, which

can usually result in order-of-magnitude improvements in program

performance. Agreed.



Depends a lot. Does the compiler notice that you're calling strlen() on a

string literal? If not, you've got a function call and a loop happening

there, which can eat up a lot of cycles, and many CPUs will have cheap

ways to zero out an array.
The code I wrote is buggy in many aspects as noticed by all the experts here.
I wrote that code for just asking the question about not initialized and initialized array.The code written was not to demonstrate my expertise in C
language.I offer my apologies if it appeared that way.
Reason why i was asking this was to get a concrete idea about the above said question.So as i understand it depends on several factors which includes code
optimization.
No. Ok.No problem.






Knowing what the issues are without reference to the assembly output is

not "guessing".
I guess not you get my point.However if you still feel otherwise please let me know and I will do my best to explain more.
 
G

Geoff

So here is the problem:

Progarm 'A'
main()
{
char array[128] = {0};
memcpy(array, "testing", strlen("testing"));
}


Progarm 'B'
main()
{
char array[128];
memcpy(array, "testing", strlen("testing"));
array[strlen("testing")] = '\0';
}

Which one is better program?Definition of better: A program is better if it has less code size and executes in less cycle.

Argument 1: Program 'B' is better as it doesn't have to initialize the whole array and just need to append '\0' at the end which is just one more cycle.

Please answer this question with concrete data in any architecture i.e. ARM, x86 or anything which is available to you.

Please use disassembly to explain your point w.r.t. cycles or code size.Strictly guess is not allowed.

I believe the question might be phrased, "Is it better to initialize
all array elements to zero prior to initializing some of them to
something other than zero or is it better to leave it uninitialized
and wait until runtime?"

Program A takes the time and processor effort to initialize all 128
members and then immediately overwrites that initialization with a new
one, counting on the first initialization to provide the zero
terminator for a string. I would call this "bad practice". It violates
locality of reference and is less maintainable. What happens to
maintenance if the initialization is widely separated from the usage
of the memcpy?

Program B provides the allocation of the buffer space and then
initializes the string and provides it's own explicit termination.

Esthetically, program B is preferable, since it explicitly
zero-terminates the string and is more maintainable. The array will
typically be initialized to some value by the OS at runtime, usually
to zero for security reasons in OS like Windows or Linux, sometimes
garbage left over from other allocations in other OS. In the case of
Microsoft's compilers, they initialize memory such as this to
pre-defined values in Debug mode (i.e., 0xCC) and this can be useful
for detecting buffer overruns or programmer errors like forgetting to
zero-terminate your string and you lose this capability when you zero
the array members. They initialize to zero in Release mode. In B, the
programmer is saying, "I know this is a C string and I am handling it
as such".

Operationally, program B is preferable since it doesn't waste time
doing something the OS may already have done, doesn't waste time doing
something the implementation may have done, and only writes initial
data that is required for correct operation.

All these points are architecturally irrelevant.
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top