code snippet

K

Kaz Kylheku


In machine language, we can, for instance, disable interrupts, flush an
instruction cache, or save the registers to a stack. To show that everything
that can be done in assembly can be done in C, you have to show how these
things are done. The paper does not show such things.

The paper argues that in the domain of translating calculation formulas,
a compiler can select instructions as well as human programmer. (And that with
some extensions to C, like "char small @0x15;" or "registerx xreg;" we can even
coerce the selection of particular operands to match specific instances of
assembly language.)

This has not been controversial for decades; the paper belongs more in 1966, or
maybe 1976, than in 2006.

Still, even in this restricted domain, there are things compilers will
typically not do. For instance, select some very complex instructions, where it
is difficult to identify the pattern of C code which fits them exactly (but the
assembly language programmer can contrive the surrounding code to exploit the
CISC instruction). Or, custom microcoding: make your own machine language instruction and then use it.

Leveling the field between humans and compilers in this area required the
development of RISC architectures (in which you basically write microcode, so
there are no complex instructions that the programmer could use, and no lower
level microcode kernel to escape into to beat the compiler.)

These days, if you're finding that you can't beat the C compiler by coding in
assembly language, chances are it's in large part because the assembly language
is designed to work well as a target language for C compilers! That has not
historically been the case.

Because of the things that assembly language can do that C really cannot (by
design) assembly language is actually a better tool for bootstrapping a high
quality implementation of some high level languages.

For instance, the best quality Lisp implementations use very little or no C
internally, and, in particular, avoid compiling to C, or using C for run-time
code that is directly called from the language. You don't want the image of a
function, the basic unit of the program, to be controlled by a C compiler
because then you have all these uncertainties such as calling conventions,
register use, etc. that are only specific to a compiler, but specific to how a
given compiler is invoked.
 
I

Ian Collins

For instance, take garbage collection. Suppose that in some function there is
a statement "x = NULL", where x is local and there are no more uses of x in the
remaining block. An optimizing C compiler could simply not bother with this
assignment since x has no next use. But what if there is garbage collection?
The variable x could be the last reference to a large amount of memory, whose
reclamation will be prevented if the assignment is optimized away.

Only for as long as x remains in scope.
The C compiler does not know that x has a kind of next use: it can be visited
"behind the scenes" by the garbage collector! C compilers are GC-unfriendly in
numerous ways, one of which is this generation of semantic garbage: keeping
values in memory or registers beyond the point at which they have become
garbage in the source semantics. In assembly we don't have this problem;
since we know what we put into every memory location and register.

Again, for how long? If a value is no longer used, the optimiser will
reuse the register. If a block if dynamic memory is no longer used, why
keep the pointer to it in scope? It sounds like you are trying to
compensate form poor design, at least in the context of gc.
We would like to be able to extend the C compiler with new rules such as
"whenever a pointer variable has no next use, generate code to overwrite it
with null", but the language doesn't give us a way to direct the translation in
such ways.

I still don't see why. If the pointer is in the current scope, the work
is probably unnecessary. If not, the work may be a very expensive way
to fix a bad design.
 
I

Ian Collins

In machine language, we can, for instance, disable interrupts, flush an
instruction cache, or save the registers to a stack. To show that everything
that can be done in assembly can be done in C, you have to show how these
things are done. The paper does not show such things.

The paper argues that in the domain of translating calculation formulas,
a compiler can select instructions as well as human programmer. (And that with
some extensions to C, like "char small @0x15;" or "registerx xreg;" we can even
coerce the selection of particular operands to match specific instances of
assembly language.)

This has not been controversial for decades; the paper belongs more in 1966, or
maybe 1976, than in 2006.

Here I do agree with you. The only (relatively) recent times I've used
assembler were for the cases you mention above (in order to model an RTOS).
These days, if you're finding that you can't beat the C compiler by coding in
assembly language, chances are it's in large part because the assembly language
is designed to work well as a target language for C compilers! That has not
historically been the case.

Very true. Another reason is modern compilers can optimise and analyse
way more code in one pass than the programmer can. Gone are the days
when optimiser performance was limited by available RAM.
 
K

Kaz Kylheku

Only for as long as x remains in scope.

Yes, but that could be a long extent of computation, under which there
are lots of nested computations. E.g. if x is in the scope of some
upper level function, like main(), it is now prevented from gc for nearly whole
lifetime of the program.
Again, for how long? If a value is no longer used, the optimiser will
reuse the register. If a block if dynamic memory is no longer used, why

So you would think, but it doesn't always work out that way. Sometimes
the object is actually in memory. The variable is no longer live, and the C
compiler does not waste any time by overwriting that variable with null just
because it is no longer live, since this is of no consequence in the normal
C paradigm.

Your naive conservative garbage collector (the only kind you can realistically
achieve under C) has to treat that memory location as a live reference,
lacking the liveness info from the compiler.

Sometimes a related problem can happens. A variable holds some dynamic object,
and that variable is overwritten with a new value. However, the new value is
held in a register, while the old value had been spilled into the underlying
memory location for that variable and is persisting there.
keep the pointer to it in scope?

Okay, so how do you not keep the pointer? What is the "unkeep" operation?

Even clobbering the pointer with NULL doesn't do the trick, necessarily. The
optimizer will see: hey, this variable is no longer live at this assignment, so
just throw the assignment away.

This is okay in normal C, because if you didn't need the dynamic object, you
would have called free on it, right? A pointer to some dynamic object which
has no next use, and which is the last reference to that object is a leak under
the explicit memory management paradigm.
It sounds like you are trying to
compensate form poor design, at least in the context of gc.

One "solution" is to call a dummy external function, which receives the address
of the variable. This will force most compilers to spill the up-to-date
register-cached value into the underlying storage, clobbering any stale
value.

This is not a nice thing to have to do everywhere. (I've done this as a
reactive approach in response to confirmed cases of the problem.)
I still don't see why. If the pointer is in the current scope, the work
is probably unnecessary.

Yes, it probably is unnecessary. Except for the rare situation when this
crops up and bites you.
If not, the work may be a very expensive way
to fix a bad design.

What is the inexpensive way to fix the design?
 
I

Ian Collins

Yes, but that could be a long extent of computation, under which there
are lots of nested computations. E.g. if x is in the scope of some
upper level function, like main(), it is now prevented from gc for nearly whole
lifetime of the program.

True, but considering gc isn't a silver bullet, you have to code with it
in mind.
So you would think, but it doesn't always work out that way. Sometimes
the object is actually in memory. The variable is no longer live, and the C
compiler does not waste any time by overwriting that variable with null just
because it is no longer live, since this is of no consequence in the normal
C paradigm.

Your naive conservative garbage collector (the only kind you can realistically
achieve under C) has to treat that memory location as a live reference,
lacking the liveness info from the compiler.

Sometimes a related problem can happens. A variable holds some dynamic object,
and that variable is overwritten with a new value. However, the new value is
held in a register, while the old value had been spilled into the underlying
memory location for that variable and is persisting there.


Okay, so how do you not keep the pointer? What is the "unkeep" operation?

Limiting the pointer's scope, typically be declaring and initialising it
where it is needed and not before.
One "solution" is to call a dummy external function, which receives the address
of the variable. This will force most compilers to spill the up-to-date
register-cached value into the underlying storage, clobbering any stale
value.

This is not a nice thing to have to do everywhere. (I've done this as a
reactive approach in response to confirmed cases of the problem.)

If you had to resort to such shenanigans, was the problem one where gc
was an appropriate solution?
Yes, it probably is unnecessary. Except for the rare situation when this
crops up and bites you.


What is the inexpensive way to fix the design?

Fix it before writing the code!

Like any tool, you can't just throw a garbage collector at any bit of
code and expect optimal performance. To get the best results, you have
to write your code with garbage collection in mind. The same applies
with smart pointers in C++, you can't just change any random pointer
based to code to use them and expect the best results.

Garbage collectors aren't part of standard C and garbage collected code
isn't standard C.
 
N

Nick Keighley

"Nick Keighley" <[email protected]> ha scritto nel messaggio

I'll give up soon. Your responses seem evasive and you frequently miss
my point, either by accident or on purpose.

#for example this:
#i don't had the time full test it,
#for example one has to try that for double , long double etc
#you can write that in C or in assembly, your bsearch() can be faster
#but my error detectrion is better of yours bsearch()
i test it against double [64 bit double] too and for luck it send to stdout
the right output [afther some debug and some time to search the error
in the compare functions...]
as I've noted before I don't read code like this

#define R   return
#define P   printf
#define F   for
<snip horrid C>

#only the test program is written in the C

but WHAT DOES THE TEST PROGRAM DO?

hello?

#it is asm

I'm talking about the C program you posted.
#here not find 0, not find a value <0, find 1 the min
#value in the list > of what search 0



#it is the output of the test program

failure to repond noted. You won't explain what your C program does.
You won't explain what "10 times safer" means and you won't offer any
interpretation of your program's obscure output.

And your C code is unreadable and posting style bizzare.

<snip>

bye.
 
I

Ian Collins

And your C code is unreadable and posting style bizzare.

I can't explain the former (I doubt anyone can), but the latter is due
to his inability to use a broken Usenet client!
 
B

BartC

Walter Banks said:

That's interesting but I don't see how you can extrapolate from that and say
there's no longer any point in anyone writing assembly ever again.

You have a compiler where you've made possible to directly refer to a
register by name. You have a single line in C that increments the register
and are surprised when it generates an increment instruction for that
register! What you've really written is some inline, high-level assembly
code!

There's plenty of things a compiler can't optimise because it doesn't know
what the programmer does, and he can't put across the knowledge in the
language.

And there are some things that can't be expressed in C (someone mentioned a
carry flag in a related thread). You can of course add special language
extensions for these, but that will end up with nearly the same portability
problems as just writing a bit of assembly in the first place.
 
J

James Harris


That paper calls itself "Proof that C can match or beat assembly"!
Sadly, it is nothing of the sort. It seems to compare *bad assembly*
with compiler output and assume that because the compiler did better
than the specific poor assembly code that they compared it with we
must draw the general conclusion that C can match or beat assembly.

Don't get me wrong. I'm a fan of C but it is to no-one's benefit to
spread nonsense like the above.

The paper includes the sentence, "After all, what is a compiler but
the distilled wisdom of years of programming experience?" LOL! Cloud
fairy-tale land. The sentence shows the blind faith that some people
adhere to - possibly because they don't understand the details and
just assume the compiler is wonderful!

James
 
8

88888 Dihedral

James Harrisæ–¼ 2012å¹´1月5日星期四UTC+8上åˆ7時57分55秒寫é“:
That paper calls itself "Proof that C can match or beat assembly"!
Sadly, it is nothing of the sort. It seems to compare *bad assembly*
with compiler output and assume that because the compiler did better
than the specific poor assembly code that they compared it with we
must draw the general conclusion that C can match or beat assembly.

Don't get me wrong. I'm a fan of C but it is to no-one's benefit to
spread nonsense like the above.

The paper includes the sentence, "After all, what is a compiler but
the distilled wisdom of years of programming experience?" LOL! Cloud
fairy-tale land. The sentence shows the blind faith that some people
adhere to - possibly because they don't understand the details and
just assume the compiler is wonderful!

James

We are not at the era that C was competing with Fortran and Pascal.
At that kind of battles, programers supporting C just helped to
spread the suspicious concepts that C was a high level language to
replace Pacal, Forth and etc..

Now who's gonna clean the mess?
 
N

Nick Keighley

James Harrisæ–¼ 2012å¹´1月5日星期四UTC+8上åˆ7時57分55秒寫é“:





We are not at the era that C was competing with Fortran and Pascal.

when was that?
At that kind of  battles, programers supporting C just helped to
spread the suspicious concepts that C was a high level language to
replace Pacal, Forth and etc..

well C *is* a high level langauge. I've programmed in Pascal and liked
it (moving to C was quite traumatic- "what are all those strange
characters?!"). But Pascal suffers from the difficulty that it needs
to be heavily extended beyond its standard before its any use (proper
array type, separate compilation, preset data etc.). It then becomes
non-portable. Maybe modula or ada were proper grownup versions of
pascal but they never really caught on.
Now who's gonna clean the mess?

what mess? C ain't perfect but it's pretty good.
 
K

Kleuske

when was that?

Ages ago. Read "The Cuckoo's Egg" for a glimpse. C never competed with
Pascal, though. Pascal was intended for educational purposes from the
get-go and is _quite_ good at it. C is intended for post-educational
purposes and is quite good in that respect.
well C *is* a high level langauge. I've programmed in Pascal and liked
it (moving to C was quite traumatic- "what are all those strange
characters?!"). But Pascal suffers from the difficulty that it needs to
be heavily extended beyond its standard before its any use (proper array
type, separate compilation, preset data etc.). It then becomes
non-portable. Maybe modula or ada were proper grownup versions of pascal
but they never really caught on.

Oberon comes to mind, but, like you said, none of the Pascal-ish languages
gained much popularity. I would not call Ada a successor to Pascal. Modula2/3
are, though.
what mess? C ain't perfect but it's pretty good.

There are two types of programming languages: those everybody bitches about
and those nobody uses (Stroustrup).
 
8

88888 Dihedral

Nick Keighleyæ–¼ 2012å¹´1月6日星期五UTC+8下åˆ4時40分53秒寫é“:
when was that?


well C *is* a high level langauge. I've programmed in Pascal and liked
it (moving to C was quite traumatic- "what are all those strange
characters?!"). But Pascal suffers from the difficulty that it needs
to be heavily extended beyond its standard before its any use (proper
array type, separate compilation, preset data etc.). It then becomes
non-portable. Maybe modula or ada were proper grownup versions of
pascal but they never really caught on.

ADA is designed for the military and the defense industry.

Pascal was used in NASA before in the early 80's.

There are still many object pascal programmers.

I think that unix, linux and even MS windows are all written in C
is the true force driving so many programmers to pick up C.
 

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

Similar Threads

code 34
URGENT 1
comparison error 12
code 50
error 28
Q for a source code in an exercise 1
no error by fscanf on reading from output file 18
malloc 40

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,042
Latest member
icassiem

Latest Threads

Top