c / c++ : is it end of era ?

J

jacob navia

Randy Howard a écrit :
DAMM!!!!!
I sent you the wrong one.

Here is the one with the necessary corrections for gcc.

1) new variable c, is incremented at
each function call. Then the compiler
cab't optimize the call away.

To avoid that the variable is discarded
main returns that value


jacob navia a écrit :
I have sent you elsethread the corrected program.
Since now gcc optimizes even when it is not told
to do that, you have to trick it into generating code
for the program you wrote, not for the program gcc
think you should have written.

#include <stdio.h>
#include <time.h>
#include <string.h>
#define MAXITER 10000000
int main(void){
char s[4096];
int i,c=0;
time_t t,tStrchr,tMemchr;

for (i=0; i<sizeof(s)-1;i++) {
s = 'a';
}
s[sizeof(s)-1] = 0;
t = time(NULL);
for (i=0; i<MAXITER;i++) {
if (strchr(s,'1'))
c++;
;

}
tStrchr= time(NULL) - t;
printf("Time for strchr=%d\n",tStrchr);
t = time(NULL);
for (i=0; i<MAXITER;i++) {


if( memchr(s,'1',sizeof(s)))
c++;
}
tMemchr=time(NULL)-t;
printf("Time for memchr=%d\n",tMemchr);

return c;





Again, I had to reduce the MAXITER value by dividing it by 10 to get
reasonable run times.

Anyway, here is the output:
Time for strchr=17
Time for memchr=13

Okay, you managed to make gcc on the PPC G5 hate them both now. I'm
not sure what that is supposed to prove. Are we to assume people care
about best performance when compiling with optimization turned off?


What I wanted to prove is just that since strchr must test
TWO characters: zero AND the character searched, it must be
slower than memchr that tests only if the count is exhausted.

Counted strings then, can use a memchr function to search
for a character since the count is known. strchr is much faster
then for those strings.

PHEW!!!!

What I thought would be evident for everyone was kind
of difficult to prove, specially since gcc seems to optimize
things when nobody is asking for it.

I personally think that a compiler should TRANSLATE the
program AS IS, not be some kind of artificial intelligence
machine that decide how you should have written the
program... specially because they guess WRONG in
some cases.
 
D

Dik T. Winter

> Andrew Sidwell a écrit : .... ....
> I explicitely said that you should NOT set any optimizations, and you
> compiled with O0. O0 DOES some optimizations, so this is quite dangerous
> with benchmarks.

From the gcc man page:
-O0 Do not optimize.
 
A

Andrew Sidwell

jacob said:
Obviously there is something wrong since in a MUCH faster machine
for 100 million iterations I take 84/43 SECONDS and you take not even
a second...

I explicitely said that you should NOT set any optimizations, and you
compiled with O0. O0 DOES some optimizations, so this is quite dangerous
with benchmarks. I would suggest that you use this program without any
optimizations at all:

The man page for gcc states that -O0 is the default, and so your own
results are tainted in a similar manner.

The additions to the variable "c" disable any optimization
of the calls away. Besides, main returns that value
and this means that gcc must generate the code as told.

It is very disappointing that compilers optimize when told
not to!!!

I get:
Time for strchr=394
And the time for memchr was getting on for fifty minutes...

Changing MAXITER to 100000, I get (terminated early because of the time
it was taking):

dougal(~/navia) time ./a.out
Time for strchr=3

real 0m39.707s
user 0m31.120s
sys 0m0.250s


Andrew Sidwell
 
J

jacob navia

Andrew Sidwell a écrit :
The man page for gcc states that -O0 is the default, and so your own
results are tainted in a similar manner.




I get:
Time for strchr=394
And the time for memchr was getting on for fifty minutes...

Changing MAXITER to 100000, I get (terminated early because of the time
it was taking):

dougal(~/navia) time ./a.out
Time for strchr=3

real 0m39.707s
user 0m31.120s
sys 0m0.250s


Andrew Sidwell

You should of course lower the iterations since they
are machine dependent!!!

It really depends on the couple/libc implementation and processor.

I did not know that O0 was the default. In any case, I do get
those results in the linux machine. It would be interesting to lower
the count and to try again if possible.

Which version of gcc are you using?
 
K

Keith Thompson

jacob navia said:
Dave Vandervies a écrit :
jacob navia said:
root@ubuntu:/tmp# gcc tmemchr.c
root@ubuntu:/tmp# ./a.out
Time for strchr=51
Time for memchr=27 [...]

How I did that?
This is Left As An Exercise For The Reader.
I don't think I'll bother. Since you don't seem to be inclined to be
cooperative, it's Highly Unlikely to be worth my time and energy to
figure out why you're claiming results that can't be replicated here.
dave

#include <stdio.h>
#include <time.h>
#include <string.h>
#define MAXITER 10000000
int main(void){
char s[4096];
int i,c=0;
time_t t,tStrchr,tMemchr;

for (i=0; i<sizeof(s)-1;i++) {
s = 'a';
}
s[sizeof(s)-1] = 0;
t = time(NULL);
for (i=0; i<MAXITER;i++) {
if (strchr(s,'1'))
c++;
}
tStrchr= time(NULL) - t;
printf("Time for strchr=%d\n",tStrchr);
t = time(NULL);
for (i=0; i<MAXITER;i++) {
if (memchr(s,'1',sizeof(s)))
c++;
}
tMemchr=time(NULL)-t;
printf("Time for memchr=%d\n",tMemchr);
return c;
}


You're still printing your time_t values incorrectly. "%d" expects a
value of type int. I suggest:

printf("Time for memchr=%lu\n", (unsigned long)tMemchr));

Subtracting time_t values is not a good way to measure performance.
You're measuring wall-clock time, not CPU time. And subtracting
time_t values doesn't necessarily give you a meaningful result (which
is why the difftime() function exists). You'd be better off using the
clock() function rather than the time() function.

I've gotten the following results on various platforms:

x86:
Time for strchr=33
Time for memchr=18

IA-64:
Time for strchr=16
Time for memchr=8

PowerPC:
Time for strchr=46
Time for memchr=127

PowerPC64:
Time for strchr=158
Time for memchr=239

(I'm running it on a SPARC as well, but I've lost patience waiting for
the output.)

So memchr is significantly faster on some systems, and significantly
slower on others.
 
R

Randy Howard

Randy Howard a écrit :
DAMM!!!!!
I sent you the wrong one.

Here is the one with the necessary corrections for gcc.

1) new variable c, is incremented at
each function call. Then the compiler
cab't optimize the call away.

To avoid that the variable is discarded
main returns that value


jacob navia a écrit :

I have sent you elsethread the corrected program.
Since now gcc optimizes even when it is not told
to do that, you have to trick it into generating code
for the program you wrote, not for the program gcc
think you should have written.

#include <stdio.h>
#include <time.h>
#include <string.h>
#define MAXITER 10000000
int main(void){
char s[4096];
int i,c=0;
time_t t,tStrchr,tMemchr;

for (i=0; i<sizeof(s)-1;i++) {
s = 'a';
}
s[sizeof(s)-1] = 0;
t = time(NULL);
for (i=0; i<MAXITER;i++) {
if (strchr(s,'1'))

c++;
;

}
tStrchr= time(NULL) - t;
printf("Time for strchr=%d\n",tStrchr);
t = time(NULL);
for (i=0; i<MAXITER;i++) {

if( memchr(s,'1',sizeof(s)))
c++;

}
tMemchr=time(NULL)-t;
printf("Time for memchr=%d\n",tMemchr);

return c;

}





Again, I had to reduce the MAXITER value by dividing it by 10 to get
reasonable run times.

Anyway, here is the output:
Time for strchr=17
Time for memchr=13

Okay, you managed to make gcc on the PPC G5 hate them both now. I'm
not sure what that is supposed to prove. Are we to assume people care
about best performance when compiling with optimization turned off?


What I wanted to prove is just that since strchr must test
TWO characters: zero AND the character searched, it must be
slower than memchr that tests only if the count is exhausted.

Counted strings then, can use a memchr function to search
for a character since the count is known. strchr is much faster
then for those strings.

PHEW!!!!

What I thought would be evident for everyone was kind
of difficult to prove, specially since gcc seems to optimize
things when nobody is asking for it.

I personally think that a compiler should TRANSLATE the
program AS IS, not be some kind of artificial intelligence
machine that decide how you should have written the
program... specially because they guess WRONG in
some cases.


Given that the compiler generates code which executes in 0 time, versus
like 2 minutes as you wrote it, I'll take the compiler's version. :)
 
S

Stephen Sprunk

jacob navia said:
Stephen Sprunk a écrit :

I have implemented operator overloading in the lcc-win32
coimpiler system. I think it is an improvement to C, without
incurring with all the associated costs of C++.

So was C++ at first :)

You're free, of course, to add any extensions you want to your product,
but any discussion you have _here_ needs to be confined to Standard C,
which you well know. Quit using this forum as a soapbox to market your
product and advocate something which is not C. If you wish to discuss
changing C to include your extensions, feel free to visit comp.std.c.
Here, please limit your discussion to how your product behaves when
invoked in a standards-compliant mode (if you have one).

And no, nobody is out to get you. The GCC and MSVC folks get the same
treatment, and for the same reason. You're the only one that doesn't
get the concept of topicality.

S
 
D

Dik T. Winter

> The additions to the variable "c" disable any optimization
> of the calls away. Besides, main returns that value
> and this means that gcc must generate the code as told.

The variable c is not needed for that. It is sufficient that the return
value of the function is used in some way (e.g.
if(strcgr(s, '1'));
is sufficient). If the result is not used, gcc removes the call, even
with -O0.
 
J

jacob navia

Dik T. Winter a écrit :
The variable c is not needed for that. It is sufficient that the return
value of the function is used in some way (e.g.
if(strcgr(s, '1'));
is sufficient). If the result is not used, gcc removes the call, even
with -O0.

I see that as a bug. Why it removes things when not
asked for optimizations???

In a more philosophical mood, I think a compiler
is a TRANSLATOR of MY program, not something
that translates my program as it thinks I should have written
it...
 
R

Richard Heathfield

jacob navia said:
Dik T. Winter a écrit :

I see that as a bug. Why it removes things when not
asked for optimizations???

The Standard doesn't require it not to, so it's not a bug.
 
J

jacob navia

Richard Heathfield a écrit :
jacob navia said:




The Standard doesn't require it not to, so it's not a bug.

It is, since we are calling memchr and strchr not
for their result but for their side-effects.

It has a wrong table of functions without side-effects
and thinks that they can be only called for
their results.

We are calling it for their side effects: they take
time to do their stuff, and that table it has is
WRONG.
 
C

Chris Dollin

jacob said:
Dik T. Winter a écrit :

I see that as a bug. Why it removes things when not
asked for optimizations???

Why not, if it's not relevant to the program's result?

The border between "optimisation" and "unstupid code generation" is
a wide and fuzzy one.
In a more philosophical mood, I think a compiler
is a TRANSLATOR of MY program, not something
that translates my program as it thinks I should have written
it...

A good translator will produce a result that efficiently reflects
the intended effect of the original. If that translation isn't
a trivial composition of trivial sub-translations, so much the
worse for trivia.
 
R

Richard Heathfield

jacob navia said:
Richard Heathfield a écrit :

It is, since we are calling memchr and strchr not
for their result but for their side-effects.

The Standard does not specify any side effects for either memchr or strchr,
so the fault is with the programmer who expects such side effects to occur.
 
K

Keith Thompson

jacob navia said:
Richard Heathfield a écrit :

Because the result of the call is not used.
It is, since we are calling memchr and strchr not
for their result but for their side-effects.

It has a wrong table of functions without side-effects
and thinks that they can be only called for
their results.

We are calling it for their side effects: they take
time to do their stuff, and that table it has is
WRONG.

What side effects?

Show us a program whose *visible* behavior when compiled under gcc is
inconsistent with the requirements of the standard. (Remember that
the standard doesn't impose any timing requirements.) If you can do
that, you'll have found a bug, assuming you've invoked gcc in a
conforming mode.

If you write
x = x + 1;
do you want the compiler (if invoked in a "non-optimizing" mode) to
generate code to load the value of x, load the value 1, add them, and
store the result back in x? Or would you be satisfied if it generated
a single increment instruction that achieves exactly the same thing?
Do you insist on distinct generated code for each of the following:
x = x + 1;
x += 1;
x ++;
++ x;
or are willing to accept the compiler's author's judgement that
they're all semantically identical?

Compilers can perform some optimizations (i.e., not-quite-literal
translations of source code to object code) even if you don't ask for
optimization. In my opinion, there's nothing wrong with this, but of
course you're entitled to your own contrary opinion. What is *not* a
matter of opinion, though, is that this does not violate the standard.

Apparently the authors of gcc felt that this optimization was easy and
safe enough to do in "-O0" mode. They apparently didn't feel it was
necessary to cater to the tiny minority of programs whose behavior
depends on wasted CPU time. I tend to agree with them.

memchr() and strchr() have no side effects (unless you consider
wasting CPU time to be a side effect), and the compiler is under no
obligation to generate code that merely wastes CPU time if the result
is not used. If you want gcc to have a mode in which function calls
are never optimized away, take it up with the gcc maintainers (try
gnu.gcc.bug) -- or just write code that uses the result so gcc *can't*
optimize the calls away (which is what you did later anyway).
 
N

Nick Keighley

jacob said:
Keith Thompson a écrit :


No. The big difference is that byte scan is hardwired in some
processors, what makes it considerably FASTER than
searching for a zero byte OR the searched character

are you *sure* about that? Just because an instruction set includes
a memcpy doesn't mean its faster than using multiple instructions.
Such an instruction begins to look very CISC like. I believe the VAX
had an instruction to calculate an arbitary CRC. Modern designs
don't.

I'm pretty sure the Z80 byte copy was *slower* than hand coded
instructions.
 
S

Stephen Sprunk

jacob navia said:
No. The big difference is that byte scan is hardwired in some
processors, what makes it considerably FASTER than
searching for a zero byte OR the searched character

You're living in the 70s and 80s. No instruction is "hardwired" in
modern CISC chips; they're decoded into RISC instructions. A "byte
scan" instruction may well execute slower than writing your own loop
because the microcode engine isn't all that fast (and, in some chips,
has a rather low output rate and stalls other decoding that would
otherwise happen at the same time). It's not a guaranteed win.

For the same reason, modern compilers skip the x86 ENTER/LEAVE
instructions in favor of emitting their own prolog/epilog, except when
optimizing for size. Ditto for nearly every other microcoded
instruction; they're just slow. And, of course, this causes a vicious
cycle; CPU designers don't optimize that part of the chip because
compilers don't use those instructions. Lather, rinse, repeat...

S
 
R

Richard Tobin

Stephen Sprunk said:
You're living in the 70s and 80s. No instruction is "hardwired" in
modern CISC chips; they're decoded into RISC instructions. A "byte
scan" instruction may well execute slower than writing your own loop
because the microcode engine isn't all that fast (and, in some chips,
has a rather low output rate and stalls other decoding that would
otherwise happen at the same time). It's not a guaranteed win.
For the same reason, modern compilers skip the x86 ENTER/LEAVE
instructions in favor of emitting their own prolog/epilog

Aren't ENTER and LEAVE slower because they implement a function call
protocol more complicated than that usually required, rather than for
the reasons you listed? In particular, they can handle "displays" as
used for nested procedures, and provide a frame pointer which can
often be omitted.

-- Richard
 
C

Chris Hills

I started programming with c. Lot of projects are being done in C++. We
have to move in THE C++.
I read around 3 - 4 books (including Faqs, stroustrup) on c++. What i
found in most of the book is that they criticize c language and c
programmer. And they silently run away from good feature of C.
They have sentence like , "you have to unlearn c to learn C++".

is it the end of C era ?
Stroustrup and writers of Faqs are gurus of technologies. These people
are commenting on C language.
should we believe them?
somewhere it is demoralizing for c programmer.

I just wanted to know what other people thinks on this .

The use of C died out a bit in the PC world but in the (much larger and
still growing) embedded world C is still the main language. There is
also some use of C++

C++ came from C90.
C has moved on and diverged from that point
C++ also moved on but in a different direction.
Therefore C and C++ look similar but may do different things even where
the syntax is similar.

C is a modular/structured language C++ is OO and as such needs a
different mindset for the design of programs.

Whilst C is still going strong C++ is loosing out to Java, C# and
C++/CLI so C++ may die out (or rather evolve) before C does.
 
C

Chris Hills

Richard Heathfield said:
Chris Hills said:



Nit: C++ pre-existed C90 by several years.

C++ started evolving before 1990 but it fixed on the C90 standard as a
basis . Look in your copy of the C++ standard.
 

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,780
Messages
2,569,611
Members
45,269
Latest member
vinaykumar_nevatia23

Latest Threads

Top