goto scope for extremelly fast code

  • Thread starter Thread starter Dave
  • Start date Start date
D

Dave

I'm building a research application that needs to be a super speed demon. I
decided that one way to do this is to use goto loops instead of while()
loops when I need them. that way, instead of checking the variable inside
the while() all it has to do is continue looping until another goto
statement is used to change the direction of the program. the problem I ran
into is that I can't call a goto statement from one function when the place
I want it to go to is in another function. How do I access the "label"(place
I want to go to) from a different function?
Dave
 
Dave said:
I'm building a research application that needs to be a super speed demon. I
decided that one way to do this is to use goto loops instead of while()
loops when I need them. that way, instead of checking the variable inside
the while() all it has to do is continue looping until another goto
statement is used to change the direction of the program. the problem I ran
into is that I can't call a goto statement from one function when the place
I want it to go to is in another function. How do I access the "label"(place
I want to go to) from a different function?

It's extremely bad karma to do that. What I mean is that the unforseen
consequences of complicating your program flow with goto's intead of more
sensable looping constructs will make you fail. It's like a greek tragedy:
it's hubris to think you can outsmart the compiler, and in the third act,
your program will die.

Moreover checking a variable in a loop is extremely cheap. For speed, keep
your code small and simple. Let the compiler, optimizer and L1 cache do the
rest.

David
 
The trouble I inherently have with this whole approach is
that you're tradnig one thing for another, and I don't see
where the speed performance is going to come into play, if
you think about what is going to really happen under the
hood. Consider this:

:x
// do some stuff
goto x

That looks fine and good, because the loop just goes round
and round and does no checking. But, the tradeoff here is
that it will be an infinite loop, unless you make some
condition become true, and then test for that condition,
to make the loop exit... and while() accomplishes that
just fine.

As for how to jump to one point in one fxn from another
fxn, well.... You could call that 2nd fxn and pass it a
number and test that number and, based on that, jump to a
particular point in code. Passing an integer and then
using switch case would prob. be the best route to go
here. I don't want to sound like I'm being negative and
critical of you, but "goto" is not really a very effective
thing in C, or any other language for that matter. It's
there to support backward compatibility with old (like
1980) line numbered BASIC, and in more modern languages,
sloppy programmers, and shouldn't even be a part of the
language, because there are always better ways to
accomplish the same tasks.

I apologize if that's not quite what you're looking for,
and I'm not saying you're a sloppy programmer-- I
understand yuor question is of a research nature. My
point is simply that I don't see a way around the
inevitable fact that, if you have a non-conditional loop
(like goto), then you're still going to have to test for
something every time through or it will run infinitely.

JIM
 
David Browne said:
demon.

It's extremely bad karma to do that. What I mean is that the unforseen
consequences of complicating your program flow with goto's intead of more
sensable looping constructs will make you fail. It's like a greek tragedy:
it's hubris to think you can outsmart the compiler, and in the third act,
your program will die.

Moreover checking a variable in a loop is extremely cheap. For speed, keep
your code small and simple. Let the compiler, optimizer and L1 cache do the
rest.

David
*****
well, you have to understand that I really do need the speed. the code
I want to write is sooo infinitely time consuming that I need every little
bit of speed I can get. and I mean every little bit. in fact, time is the
limiting factor in the research. it has to do with calculating chemical
physics and simulating it. the reason the loop is so important is because
the code basically is a loop of: calculate position, display graphics, check
system events, and loop again. so basically this thing is a very fast loop
that continues indefinetly. that's why its important for me to use events
and goto's instead of using while statements.
any suggestions for solving the problem?
dave
 
Jim said:
The trouble I inherently have with this whole approach is
that you're tradnig one thing for another, and I don't see
where the speed performance is going to come into play, if
you think about what is going to really happen under the
hood. Consider this:

:x
// do some stuff
goto x

That looks fine and good, because the loop just goes round
and round and does no checking. But, the tradeoff here is
that it will be an infinite loop, unless you make some
condition become true, and then test for that condition,
to make the loop exit... and while() accomplishes that
just fine.

As for how to jump to one point in one fxn from another
fxn, well.... You could call that 2nd fxn and pass it a
number and test that number and, based on that, jump to a
particular point in code. Passing an integer and then
using switch case would prob. be the best route to go
here. I don't want to sound like I'm being negative and
critical of you, but "goto" is not really a very effective
thing in C, or any other language for that matter. It's
there to support backward compatibility with old (like
1980) line numbered BASIC, and in more modern languages,
sloppy programmers, and shouldn't even be a part of the
language, because there are always better ways to
accomplish the same tasks.

I apologize if that's not quite what you're looking for,
and I'm not saying you're a sloppy programmer-- I
understand yuor question is of a research nature. My
point is simply that I don't see a way around the
inevitable fact that, if you have a non-conditional loop
(like goto), then you're still going to have to test for
something every time through or it will run infinitely.

JIM
************************
the reason it would work is because I would use events to change the
direction of the program. the loop will run until a system event, that I
set up, stops it and tells it do something else.
the method you described would work but my real problem is that the
function I'm talking about is a system event. for example, when I press a
key on the keyboard, the system will call the ProcessDialogKey() function
and that will change the direction of the program. the problem here is that
I don't call the function, and therefore I can't get any values from it
either.
even if I could get the value back, it would suffice because I would have
to handle that value inside the loop, and that would defeat the whole
purpose.
I need a way to dynamically jump into my code, anywhere I want, when a
system event occurs.
dave
 
*****
well, you have to understand that I really do need the speed. the code
I want to write is sooo infinitely time consuming that I need every little
bit of speed I can get. and I mean every little bit. in fact, time is the
limiting factor in the research. it has to do with calculating chemical
physics and simulating it. the reason the loop is so important is because
the code basically is a loop of: calculate position, display graphics, check
system events, and loop again. so basically this thing is a very fast loop
that continues indefinetly. that's why its important for me to use events
and goto's instead of using while statements.
any suggestions for solving the problem?


The problem is that you're barking up the wrong tree here. If your loop
contains GDI calls, system events, reads to large swaths of heap data, and
intensive calculations, then tweaking your loop control is several orders of
magnitute away from making any difference.

But is sounds more like a program flow control problem than a performance
problem. Perhaps if you described the program a little more, or posted some
sample code it would help.

David
 
Okay, I think I see where you're going with this now...
and I still can't help but wonder exactly why you're so
concerned about very cheap operations like a simple
variable test, when all the overhead involved in trapping
events makes those little tests pale in cmoparison. Even
the simplet event hadler operation, start to finish, will
end up generating about eight branch and link
instructions. Anyway....

You still have a number of other options. For one thing,
since you're writing the handler, you can do anything you
want with it. If you want the handler to snatch control
of your code in the middle of one fxn, and then pass
control to some point inside another fxn, you could always
create a global (or static, if you're doing this in a
class) variable "int WhereAmI" and then in fxn a() set it
to some value. When fxn b() (your event handler) takes
control, it can then call fxn c(). Fxn c() can then read
the global "WhereAmI" variable that was set to some value
by a() (or perhaps even alterd by b()... It's your
program), and can then act accordingly.

A word of caution on this though... Remember that all fxns
must termniate, and so subsequent and recursive calls to
fxns stay on the call stack. If fxn a() runs and event
handler b() runs and calls c(), remember that eventually
control is going to go back to a() to finish up whatever
it was doing before the event. Such is the nature of
event-driven programming. If that's going to pose a
problem, then you could create a fxn pointer (a delegate
fxn in C#) and then have the event handler set it. This
is how event handlers pass aruond "callback fxns", and is
actually how most event handlers work anyway. So, in a()
you could create a delegate for the signatuer of c() and
then have b() add c() to the delegate.... and back in a()
test to see if the delegate is null and if not, call
delegate().

which again takes us back to this whole discussion of
overhead. I have an inherent appreciation for yuor desire
to find the most efficient route from a to b.
Unfortunately, its a defacto standard that to fly from
Boston to New York in Windows, you'll have to change
planes in London after a quick stopover in LA. :) These
days, memory and resources just aren't at a premium
anymore, so most developers don't count bits and bytes
like we used to back in the days of DOS programming. The
hard-core guys do, who write the drivers and code for
video cards and stuff like that, but they're using .asm
routines on propietary hardware. You're writing code that
has to interact with an entire framework of an operating
system, but it sure if fun to learn, isn't it? :)

JIM
 
Well, another thought I have on this issue, now that you
put it THAT way.... :)

Do you understand how the GDI component of Widnows
applications works? Each time yuo press a key on the
keyboad, move the mosue, or you (or various components
within the system itself) performa any of a myriad of
operations, something in the GDI inevitably changes.
Windows would come to a screeching halt if it updated the
GDI "every time" "anything" happened. What it does, to
put it very simply, is it puts the system processing and
the GDI processing into separate application threads. The
GDI thread is only awakened to do something when the
system isn't "too busy". Kind of like when your wife
tells you to wash the dishes, cut the grass, and paint the
garage.... and you prioritize and get to it when you're
done watching football and taking a nap. :)

While a discussion of threads is beyond the scope of this
discussion, and the technical aspects of it task the
limits of my knowledge of programming (especially in C#),
you might want to think about a similar scenario for your
application. Do all that heavy calculation in one thread,
and then let that thread go back and update the GDI either
when it's not too busy or at some regular interval (like
the way I nod every 15 seconds when my wife talks to me so
she knows I'm not ignoring her.) I don't mean to sound so
jovial about the subject, but seriously, often times the
way these things work under the hood is strikingly similar
to the way things work in real life. Think about
how "you" would do it, and then write code to mimmick that
process. :)

JIM
-----Original Message-----

"David Browne" <davidbaxterbrowne no potted
(e-mail address removed)> wrote in
 
Dave,

I've read several of the threads on this, and I think the best way for us to
help you is for you to give a better description of the effect that you
want. ie something like, "I want to do processing in a loop, and then stop
that loop when the user presses a key".

In other words, describe the problem that you're trying to solve rather than
asking us to help implement the solution you're thinking of.

I do agree with the others that you are likely worrying too much about
low-level speed effects. The JIT that is used in C# (and C++ compilers, as
well) put a lot of effort into optimizing commonly-used constructs. If you
go out on your own and do things a different way, you may end up with code
that is both slower and a lot harder to understand.

There's a lot to be said for writing something the simplest way, and then
working to make it fast.

--
Eric Gunnerson

Visit the C# product team at http://www.csharp.net
Eric's blog is at http://blogs.gotdotnet.com/ericgu/

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Thanks for all the help guys, I haven't studied each suggestion carefully
yet because they were detailed and I will look back over them after I send
this post about the basic purpose of the program
well, the program I'm trying to design basically simulates very complex
chemical reactions. The user will be able to tell it what it wants to put
into the virtual reaction box and it will calculate what would happen using
physics, which, if your wondering why, is necessary to understand any
complex reaction without prior experience.
The code for how to calculate the positions of atoms will be very very
very time consuming. In fact, do do it perfectly accurately in a reasonable
amount of time( and maybe even at all) is practically impossible. So I have
to make a comprimise with accuracy and time but there is a certain point
where you can't compromise anymore because you will have 0 accuracy. At the
moment that point is not good enough and so I need to speed of the program
as much as possible. That's basically why the program needs to be fast to
the extreme.
Basically the programming increments the virtual time of the reaction
and then updates the positions of particles. During each very small
increment in the time, it has to calculate the forces and other factors that
go into changing the position of the particles. Once its done that, it will
either continue calculating, or it will display the positions on the screen
graphically, using directx. Directx is one of the reasons I have to use a
loop too because the code for directx graphics is always a loop that goes:
calculations.display graphics... calculations.displaygraphics...
I have made a program that had similar time consumption problems and
tried a simpler approach that using goto's. what I did was copy and pasted
the code inside the loop many many times right after each other so it looked
this: While(){ calculate.display.calculate.display.calculate.display...}.
This solution allows the program to do more calculations before it has to ch
eck the variable in the while().
I guess I could use that solution, I was just hoping I could find a
better way of doing it. and from what you guys have been saying, I guess its
just not possible.
I also realized from you all have been saying is that windows takes up a
lot of cpu time anyway, so I'm thinking of networking two computers and
using one in dos mode to do the calculating and the other in windows that
would recieve the position coordinates from the calculating computer and
have nice user interface. Is that possible? to network windows and dos?
Any suggestions?
dave
 
Dave,

Have you actually verified that a goto is quicker than a 'while true'? I doubt there would be any speed difference.

Writing this in C# and then saying it is critical to optimise it down to the last goto doesn't make sense. If speed is that critical
then it should be written in C or assembler.

The fact is that you will have to check *something* in that loop, there is no way to avoid it. The best approach would be to not
check it too often, eg

int count = 0;

private void DoStuff()
{
while (true)
{
count++;
if (count > 10000)
{
//Update GUI
Application.DoEvents(); //keypresses will not get processed without this
if (count >= 20000) break;//to stop the process an event can set count to 20000
count = 0;
}
}
}
the reason it would work is because I would use events to change the
direction of the program. the loop will run until a system event, that I
set up, stops it and tells it do something else.

Your app can only do one thing at a time (provided you have a single thread). If your app is busy processing a loop you won't get
the keyPress event. Keypress events are checked in a hidden loop anyway, which I'm not sure threads would be a good idea because
the overhead of thread switching would be greater than checking a variable in the loop.
 
you're right, I guess I will just copy and paste the code inside the loop
several more times inside of the loop. I can't really use C because I have
to use directx and it is much much much easier to do in c# with the visual
aids and stuff and I doubt that c would actually be any faster but maybe I'm
wrong. if I have to use c to make it faster than I think I will have to
have two computers. one for graphics and Gui, and one for the real time
consuming calculations.
I'm not even going to consider trying to write such a complex program in
assembly language.
dave
Michael Culley said:
Dave,

Have you actually verified that a goto is quicker than a 'while true'? I
doubt there would be any speed difference.
Writing this in C# and then saying it is critical to optimise it down to
the last goto doesn't make sense. If speed is that critical
then it should be written in C or assembler.

The fact is that you will have to check *something* in that loop, there is
no way to avoid it. The best approach would be to not
check it too often, eg

int count = 0;

private void DoStuff()
{
while (true)
{
count++;
if (count > 10000)
{
//Update GUI
Application.DoEvents(); //keypresses will not get processed without this
if (count >= 20000) break;//to stop the process an event can set count to 20000
count = 0;
}
}
}


Your app can only do one thing at a time (provided you have a single
thread). If your app is busy processing a loop you won't get
the keyPress event. Keypress events are checked in a hidden loop anyway,
which I'm not sure threads would be a good idea because
 
Jim said:
Okay, I think I see where you're going with this now...
and I still can't help but wonder exactly why you're so
concerned about very cheap operations like a simple
variable test, when all the overhead involved in trapping
events makes those little tests pale in cmoparison. Even
the simplet event hadler operation, start to finish, will
end up generating about eight branch and link
instructions. Anyway....

You still have a number of other options. For one thing,
since you're writing the handler, you can do anything you
want with it. If you want the handler to snatch control
of your code in the middle of one fxn, and then pass
control to some point inside another fxn, you could always
create a global (or static, if you're doing this in a
class) variable "int WhereAmI" and then in fxn a() set it
to some value. When fxn b() (your event handler) takes
control, it can then call fxn c(). Fxn c() can then read
the global "WhereAmI" variable that was set to some value
by a() (or perhaps even alterd by b()... It's your
program), and can then act accordingly.

A word of caution on this though... Remember that all fxns
must termniate, and so subsequent and recursive calls to
fxns stay on the call stack. If fxn a() runs and event
handler b() runs and calls c(), remember that eventually
control is going to go back to a() to finish up whatever
it was doing before the event. Such is the nature of
event-driven programming. If that's going to pose a
problem, then you could create a fxn pointer (a delegate
fxn in C#) and then have the event handler set it. This
is how event handlers pass aruond "callback fxns", and is
actually how most event handlers work anyway. So, in a()
you could create a delegate for the signatuer of c() and
then have b() add c() to the delegate.... and back in a()
test to see if the delegate is null and if not, call
delegate().

which again takes us back to this whole discussion of
overhead. I have an inherent appreciation for yuor desire
to find the most efficient route from a to b.
Unfortunately, its a defacto standard that to fly from
Boston to New York in Windows, you'll have to change
planes in London after a quick stopover in LA. :) These
days, memory and resources just aren't at a premium
anymore, so most developers don't count bits and bytes
like we used to back in the days of DOS programming. The
hard-core guys do, who write the drivers and code for
video cards and stuff like that, but they're using .asm
routines on propietary hardware. You're writing code that
has to interact with an entire framework of an operating
system, but it sure if fun to learn, isn't it? :)

JIM

****
advice taken. I guess I'm stupid because I thought I had to use the same
code and use a goto to get to it. but now I realize that you're right. I
could make a function out of that code and call it whenever I like. but in
the end, I think I will use DOS to do the calculations on one computer and
windows to do the GUI on another computer. in that case I wouldn't use
events to control the program and I think I will just write a while loop
that has many the code coppied several times inside the loop so that it
doesn't have to check the while variable every loop iteration.
thanks
dave
 
Jim said:
Well, another thought I have on this issue, now that you
put it THAT way.... :)

Do you understand how the GDI component of Widnows
applications works? Each time yuo press a key on the
keyboad, move the mosue, or you (or various components
within the system itself) performa any of a myriad of
operations, something in the GDI inevitably changes.
Windows would come to a screeching halt if it updated the
GDI "every time" "anything" happened. What it does, to
put it very simply, is it puts the system processing and
the GDI processing into separate application threads. The
GDI thread is only awakened to do something when the
system isn't "too busy". Kind of like when your wife
tells you to wash the dishes, cut the grass, and paint the
garage.... and you prioritize and get to it when you're
done watching football and taking a nap. :)

While a discussion of threads is beyond the scope of this
discussion, and the technical aspects of it task the
limits of my knowledge of programming (especially in C#),
you might want to think about a similar scenario for your
application. Do all that heavy calculation in one thread,
and then let that thread go back and update the GDI either
when it's not too busy or at some regular interval (like
the way I nod every 15 seconds when my wife talks to me so
she knows I'm not ignoring her.) I don't mean to sound so
jovial about the subject, but seriously, often times the
way these things work under the hood is strikingly similar
to the way things work in real life. Think about
how "you" would do it, and then write code to mimmick that
process. :)

JIM

(e-mail address removed)> wrote in
****
good advice.
thanks
 
David Browne said:
The problem is that you're barking up the wrong tree here. If your loop
contains GDI calls, system events, reads to large swaths of heap data, and
intensive calculations, then tweaking your loop control is several orders of
magnitute away from making any difference.

But is sounds more like a program flow control problem than a performance
problem. Perhaps if you described the program a little more, or posted some
sample code it would help.

David
****
very true, I realize that now. I'm not the best programming in the world yet
but I'm learnin. so I'll try to write the code for DOS mode and put the
graphics on a different computer using a network.
 
Dave said:
you're right, I guess I will just copy and paste the code inside the loop
several more times inside of the loop.

That could work, it would reduce the number of times count is incremented.
I can't really use C because I have
to use directx and it is much much much easier to do in c# with the visual

You could put all of the code which needs to be quick into a dll in C and put all the slower GUI code into C#.
aids and stuff and I doubt that c would actually be any faster

It would be quicker.
have two computers. one for graphics and Gui, and one for the real time
consuming calculations.

That's probably not necessary, just update the graphics less often.
 
Dave said:
I also realized from you all have been saying is that windows takes up a
lot of cpu time anyway,

It only takes up a lot of time if it is doing something. If the machine is idle (besides your code) then you should have 99% or more
of the processor power. So I would say that using dos is not worth the trouble.

BTW, Have you considered writing your code in vb6? This might sound crazy but vb6 compiles natively and runs very fast, especially
if you turn on all of the compiler optimisations. I'm not sure how it compares with .net but I imagine it will be faster. You could
compile the vb6 code into a dll and use c# for the directX stuff.
 
Michael Culley said:
It only takes up a lot of time if it is doing something. If the machine is
idle (besides your code) then you should have 99% or more
of the processor power. So I would say that using dos is not worth the trouble.

BTW, Have you considered writing your code in vb6? This might sound crazy
but vb6 compiles natively and runs very fast, especially
if you turn on all of the compiler optimisations. I'm not sure how it
compares with .net but I imagine it will be faster. You could
compile the vb6 code into a dll and use c# for the directX stuff.

--
Michael Culley

******
It only takes up a lot of time if it is doing something. If the machine is
idle (besides your code) then you should have 99% or more
of the processor power. So I would say that using dos is not worth the
trouble.

oooo, I like that idea! much less trouble :). now I've got to figure out
how to stop all these damn programs, especially the spyware, from running
when I don't want them. anyone know what the only running process you need
to run windows are? when I press ctrl alt delete I can see like 20 or so
programs running and I always hate it because I never could figure out what
I need and what I don't.
dave
 
Michael Culley said:
That could work, it would reduce the number of times count is incremented.
visual

You could put all of the code which needs to be quick into a dll in C and
put all the slower GUI code into C#.
It would be quicker.


That's probably not necessary, just update the graphics less often.

--
Michael Culley

***
You could put all of the code which needs to be quick into a dll in C and
put all the slower GUI code into C#.

that's a good idea. actually my very first programming language was C. even
though that was several years ago :). I don't know exactly how to do that
but I will learn. do you know why c would be faster? it sure seems like they
are almost identical much of the time. I mean I noticed little things but
nothing that I was afraid was going to affect basic code.
 
Dave,
I don't know exactly how to do that
but I will learn.

If you started in C then you will find it easy. You can use the wizard to create a dll project, add a function eg

int __stdcall Add(int Val1, intVal2)
{
return Val1 + Val2;
}

then add a file called export.def and add to it:

Exports
Add

compile it and then reference it in C# like this

[DllImport("MyDllName.dll")]
private static extern int Add(int Val1, Val2);

(That's about my entire knowledge of C :-).
do you know why c would be faster?

High level languages like C# do additional checks to ensure that your code won't crash. For example, if you get element 100 of a 10
element array C will either crash or return data from an invalid memory location. On the other hand C# will throw an exception. So
there is this extra check in the assembly code to ensure that the array index is valid before it is used. The same applies for
something as simple as adding 2 numbers, in C the numbers will roll back around to zero but in C# an exception is thrown. You can
turn both of these checks off (eg see the unchecked keyword) but there are others that you can't.
now I've got to figure out
how to stop all these damn programs, especially the spyware, from running
when I don't want them.

Look in the startup folder in your start menu first (I'm sure you knew that bit), then look in the Run folder in the registry
(search from RunOnce, it's the one before that), then look in services. In services you can see the exe name of each service and
compare that to the task list. I don't think any of this will make much difference though because most of them will be idle anyway.

Regards,
Michael Culley
 
Back
Top