Lightning Calculator

C

CoreyWhite

I asked the question, "how do you define arithmetic?", and when I came
to an answer I understood math in a new, much clearer way. I also
happened upon a method of arithmetic optimization that really speeds up
calculations on computers.

If you wanted to define mathematics I would first define addition. The
simplest way to define addition is to create a function for every
number and say f_n(x)=x+n , where n is the number you are preforming
addition on and x is the modifying value. The problem with this is it
uses addition to define itself, so I decided to write it longhand:

f_1(x) = if x==1 then y=2 , if x==2 then y=3, if x==3 then y=4...
f_2(x) = if x==1 then y=3 , if x==2 then y=4, if x==3 then y=5...
f_3(x) = if x==1 then y=4 , if x==2 then y=5, if x==3 then y=6...
....

You could do this for every number you wished to use and define the
scope of the numers you wished to work with. I of course have not
created a table that goes up to infinity or one that can use infinite
decimal places. If I need to I will just create new functions that
work with larger numbers and more decimal places.

What I found in terms of computer programming, is that when I manually
assign values to variables I don't need to use the operators to do
arithmetic. What I like about doing it this way is it is faster.

This C++ program is an example of this kind of optimization. The lines
commented out preform the exact same function as the lines which
preform arithmetic on the variables, but the commented lines are much
faster.

Do you think we could optimize computer architecture to take advantage
of this?
Any feedback on this theory is welcome

#include <cstdlib>
#include <iostream>
#include <ctime>

using namespace std;

int main(int argc, char *argv[])
{

time_t t1, t0;
double elapsed;

time(&t0); /* start time */
for(int cnt=0; cnt<1000000000; cnt++){
int x=0;
int y=577;
x=x+y;
y=x+y;
//if(x==0 && y==577) x=577;
//if(x==577 && y==577) y=1154;

}
time(&t1);
elapsed = difftime(t1, t0);
cout<<elapsed;
system("PAUSE");
return EXIT_SUCCESS;

}
 
G

Gianni Mariani

This C++ program is an example of this kind of optimization. The lines
commented out preform the exact same function as the lines which
preform arithmetic on the variables, but the commented lines are much
faster.

The commented code does not have the same effect as the addition code.

Back to the drawing board.

BTW - I would be very surprised if this has a really significant
performance difference (when you get the code right).
 
K

Kai-Uwe Bux

I asked the question, "how do you define arithmetic?", and when I came
to an answer I understood math in a new, much clearer way. I also
happened upon a method of arithmetic optimization that really speeds up
calculations on computers.

If you wanted to define mathematics I would first define addition. The
simplest way to define addition is to create a function for every
number and say f_n(x)=x+n , where n is the number you are preforming
addition on and x is the modifying value. The problem with this is it
uses addition to define itself, so I decided to write it longhand:

f_1(x) = if x==1 then y=2 , if x==2 then y=3, if x==3 then y=4...
f_2(x) = if x==1 then y=3 , if x==2 then y=4, if x==3 then y=5...
f_3(x) = if x==1 then y=4 , if x==2 then y=5, if x==3 then y=6...
...

You could do this for every number you wished to use and define the
scope of the numers you wished to work with. I of course have not
created a table that goes up to infinity or one that can use infinite
decimal places. If I need to I will just create new functions that
work with larger numbers and more decimal places.

What I found in terms of computer programming, is that when I manually
assign values to variables I don't need to use the operators to do
arithmetic. What I like about doing it this way is it is faster.

This C++ program is an example of this kind of optimization. The lines
commented out preform the exact same function as the lines which
preform arithmetic on the variables, but the commented lines are much
faster.

Do you think we could optimize computer architecture to take advantage
of this?
Any feedback on this theory is welcome

#include <cstdlib>
#include <iostream>
#include <ctime>

using namespace std;

int main(int argc, char *argv[])
{

time_t t1, t0;
double elapsed;

time(&t0); /* start time */
for(int cnt=0; cnt<1000000000; cnt++){
int x=0;
int y=577;
x=x+y;
y=x+y;
//if(x==0 && y==577) x=577;
//if(x==577 && y==577) y=1154;

}
time(&t1);
elapsed = difftime(t1, t0);
cout<<elapsed;
system("PAUSE");
return EXIT_SUCCESS;

}

Sounds bogus to me. Here are two routines:

typedef unsigned char u_char;

inline
u_char sum ( u_char a, u_char b ) {
if ( a == 0 && b == 0 ) return 0;
if ( a == 0 && b == 1 ) return 1;
if ( a == 0 && b == 2 ) return 2;
if ( a == 0 && b == 3 ) return 3;
if ( a == 0 && b == 4 ) return 4;
if ( a == 0 && b == 5 ) return 5;
if ( a == 0 && b == 6 ) return 6;
if ( a == 0 && b == 7 ) return 7;

if ( a == 1 && b == 0 ) return 1;
if ( a == 1 && b == 1 ) return 2;
if ( a == 1 && b == 2 ) return 3;
if ( a == 1 && b == 3 ) return 4;
if ( a == 1 && b == 4 ) return 5;
if ( a == 1 && b == 5 ) return 6;
if ( a == 1 && b == 6 ) return 7;
if ( a == 1 && b == 7 ) return 8;

if ( a == 2 && b == 0 ) return 2;
if ( a == 2 && b == 1 ) return 3;
if ( a == 2 && b == 2 ) return 4;
if ( a == 2 && b == 3 ) return 5;
if ( a == 2 && b == 4 ) return 6;
if ( a == 2 && b == 5 ) return 7;
if ( a == 2 && b == 6 ) return 8;
if ( a == 2 && b == 7 ) return 9;

if ( a == 3 && b == 0 ) return 3;
if ( a == 3 && b == 1 ) return 4;
if ( a == 3 && b == 2 ) return 5;
if ( a == 3 && b == 3 ) return 6;
if ( a == 3 && b == 4 ) return 7;
if ( a == 3 && b == 5 ) return 8;
if ( a == 3 && b == 6 ) return 9;
if ( a == 3 && b == 7 ) return 10;

if ( a == 4 && b == 0 ) return 4;
if ( a == 4 && b == 1 ) return 5;
if ( a == 4 && b == 2 ) return 6;
if ( a == 4 && b == 3 ) return 7;
if ( a == 4 && b == 4 ) return 8;
if ( a == 4 && b == 5 ) return 9 ;
if ( a == 4 && b == 6 ) return 10;
if ( a == 4 && b == 7 ) return 11;

return 0;

}

inline
u_char sum1 ( u_char a, u_char b ) {
return( a + b );
}



Would you expect sum1 to be faster? You are right that it does not add,
however it performs quite a few tests, which also cost time.



Best

Kai-Uwe Bux
 
B

benben

I asked the question, "how do you define arithmetic?", and when I came
to an answer I understood math in a new, much clearer way. I also
happened upon a method of arithmetic optimization that really speeds up
calculations on computers.

If you wanted to define mathematics I would first define addition. The
simplest way to define addition is to create a function for every
number and say f_n(x)=x+n , where n is the number you are preforming
addition on and x is the modifying value. The problem with this is it
uses addition to define itself, so I decided to write it longhand:

f_1(x) = if x==1 then y=2 , if x==2 then y=3, if x==3 then y=4...
f_2(x) = if x==1 then y=3 , if x==2 then y=4, if x==3 then y=5...
f_3(x) = if x==1 then y=4 , if x==2 then y=5, if x==3 then y=6...
...

You could do this for every number you wished to use and define the
scope of the numers you wished to work with. I of course have not
created a table that goes up to infinity or one that can use infinite
decimal places. If I need to I will just create new functions that
work with larger numbers and more decimal places.

What I found in terms of computer programming, is that when I manually
assign values to variables I don't need to use the operators to do
arithmetic. What I like about doing it this way is it is faster.

This C++ program is an example of this kind of optimization. The lines
commented out preform the exact same function as the lines which
preform arithmetic on the variables, but the commented lines are much
faster.

Do you think we could optimize computer architecture to take advantage
of this?
Any feedback on this theory is welcome

#include <cstdlib>
#include <iostream>
#include <ctime>

using namespace std;

int main(int argc, char *argv[])
{

time_t t1, t0;
double elapsed;

time(&t0); /* start time */
for(int cnt=0; cnt<1000000000; cnt++){
int x=0;
int y=577;
x=x+y;
y=x+y;
//if(x==0 && y==577) x=577;
//if(x==577 && y==577) y=1154;

}
time(&t1);
elapsed = difftime(t1, t0);
cout<<elapsed;
system("PAUSE");
return EXIT_SUCCESS;

}

Corey, what makes you think the commented lines are faster than the addtion
operator?

As far as I know, and assuming no compiler optimization is used, each
commented line can be translated into two subtraction (SUB) operations
(comparison on integers is substraction and check zero), a logical AND
operation, and a very slow (as compared to addtion and subtraction) jump
(JMP) operation, followed by an assignment (MOV) operation. So far you have
x and y, result of (x==0), result of (y==577), result of (x==0 && y==577),
it is unlikely that all operands are stored in register for fast access.

A simple addtion is just an addtion (ADD) operation plus an assignment
operation. And because only x, y and result of x+y are stored and read (the
result of x+y naturally in the ACC), it is likely that the whole operation
is done on registers, which means very fast.

With compiler optimization, the compiler probably sees the definition of x
and y followed by assignment to x and y, so the values of x and y within the
iteration scope are entirely predictable (x = 577 and y = 1154), that it
wouldn't bother to add anyway.

Finally, the uncommented code is much more explicit, simple, readable than
the one you devised.

Regards,
Ben
 
C

CoreyWhite

Aha, so you want to see this in assembly, and you want this to work in
a way that actually saves time even when working with cases that are
not as special as an addition operation on two variables that have
values you can be sure of.

Try this piece of code that uses inline assembly and does a bit of
division. The program is about 10 times faster when done the 'long
way'. I hope you can see how it all depends on what sort of operations
you are doing, and the scope of the information you are working with.
You have to find a balance, and this method may not always be useful
for everything, especially in high level languages like C++.

int main(int argc, char *argv[]){
time_t t1, t0;
double elapsed;
time(&t0); /* start time */
for(int cnt=0; cnt<2000000000; cnt++){
asm("mov $0x04, %ax\n\t"
"mov $0x02, %bx\n\t"
"cmp $0x04, %ax\n\t"
"cmp $0x02, %bx\n\t"
"mov $0x02, %ax\n\t");
}
time(&t1);
elapsed = difftime(t1, t0);
cout<<"Time: "<<elapsed<<" seconds."<<endl;

time(&t0); /* start time */
for(int cnt=0; cnt<2000000000; cnt++){
asm("mov $0x04, %ax\n\t"
"mov $0x02, %bx\n\t"
"div %bx, %ax\n\t");
}
time(&t1);
elapsed = difftime(t1, t0);

cout<<"Time: "<<elapsed<<" seconds."<<endl;


system("PAUSE");
return EXIT_SUCCESS;
}
 
B

benben

Aha, so you want to see this in assembly, and you want this to work in
a way that actually saves time even when working with cases that are
not as special as an addition operation on two variables that have
values you can be sure of.

Try this piece of code that uses inline assembly and does a bit of
division. The program is about 10 times faster when done the 'long
way'. I hope you can see how it all depends on what sort of operations
you are doing, and the scope of the information you are working with.
You have to find a balance, and this method may not always be useful
for everything, especially in high level languages like C++.

int main(int argc, char *argv[]){
time_t t1, t0;
double elapsed;
time(&t0); /* start time */
for(int cnt=0; cnt<2000000000; cnt++){
asm("mov $0x04, %ax\n\t"
"mov $0x02, %bx\n\t"
"cmp $0x04, %ax\n\t"
"cmp $0x02, %bx\n\t"
"mov $0x02, %ax\n\t");
}
time(&t1);
elapsed = difftime(t1, t0);
cout<<"Time: "<<elapsed<<" seconds."<<endl;

time(&t0); /* start time */
for(int cnt=0; cnt<2000000000; cnt++){
asm("mov $0x04, %ax\n\t"
"mov $0x02, %bx\n\t"
"div %bx, %ax\n\t");

Why is that a div here?
 
J

Jim Langston

I asked the question, "how do you define arithmetic?", and when I came
to an answer I understood math in a new, much clearer way. I also
happened upon a method of arithmetic optimization that really speeds up
calculations on computers.

If you wanted to define mathematics I would first define addition. The
simplest way to define addition is to create a function for every
number and say f_n(x)=x+n , where n is the number you are preforming
addition on and x is the modifying value. The problem with this is it
uses addition to define itself, so I decided to write it longhand:

f_1(x) = if x==1 then y=2 , if x==2 then y=3, if x==3 then y=4...
f_2(x) = if x==1 then y=3 , if x==2 then y=4, if x==3 then y=5...
f_3(x) = if x==1 then y=4 , if x==2 then y=5, if x==3 then y=6...
...

You could do this for every number you wished to use and define the
scope of the numers you wished to work with. I of course have not
created a table that goes up to infinity or one that can use infinite
decimal places. If I need to I will just create new functions that
work with larger numbers and more decimal places.

What I found in terms of computer programming, is that when I manually
assign values to variables I don't need to use the operators to do
arithmetic. What I like about doing it this way is it is faster.

This C++ program is an example of this kind of optimization. The lines
commented out preform the exact same function as the lines which
preform arithmetic on the variables, but the commented lines are much
faster.

Do you think we could optimize computer architecture to take advantage
of this?
Any feedback on this theory is welcome

#include <cstdlib>
#include <iostream>
#include <ctime>

using namespace std;

int main(int argc, char *argv[])
{

time_t t1, t0;
double elapsed;

time(&t0); /* start time */
for(int cnt=0; cnt<1000000000; cnt++){
int x=0;
int y=577;
x=x+y;
y=x+y;
//if(x==0 && y==577) x=577;
//if(x==577 && y==577) y=1154;

}
time(&t1);
elapsed = difftime(t1, t0);
cout<<elapsed;
system("PAUSE");
return EXIT_SUCCESS;

}

Well, this is fine for the SPECIFIC values of 577. But waht about 576. And
575. And 574. And...

So in reality you would need to go through 576 if statements before you got
to 577. That's 577 compares.

Do that same code for adding teh intergers 0 to 20 and then test and you'll
see it's much slower.
 
C

Corey White

Aha, so you want to see this in assembly, and you want this to work in
a way that actually saves time even when working with cases that are
not as special as an addition operation on two variables that have
values you can be sure of.

Try this piece of code that uses inline assembly and does a bit of
division. The program is about 10 times faster when done the 'long
way'. I hope you can see how it all depends on what sort of operations
you are doing, and the scope of the information you are working with.
You have to find a balance, and this method may not always be useful
for everything, especially in high level languages like C++.

int main(int argc, char *argv[]){
time_t t1, t0;
double elapsed;
time(&t0); /* start time */
for(int cnt=0; cnt<2000000000; cnt++){
asm("mov $0x04, %ax\n\t"
"mov $0x02, %bx\n\t"
"cmp $0x04, %ax\n\t"
"cmp $0x02, %bx\n\t"
"mov $0x02, %ax\n\t");
}
time(&t1);
elapsed = difftime(t1, t0);
cout<<"Time: "<<elapsed<<" seconds."<<endl;

time(&t0); /* start time */
for(int cnt=0; cnt<2000000000; cnt++){
asm("mov $0x04, %ax\n\t"
"mov $0x02, %bx\n\t"
"div %bx, %ax\n\t");

Why is that a div here?

It divides ax by bx and stores the result in ax.


I wanted to show off a newer version of this program that is a little
more sophisticated and utilizes better assembly. Tell me if there is
anything you don't understand about this code. I thought you might be
able to appreciate it, because there are more options for the integers
which we divide. It can do 4/2 8/2 16/2 32/2 64/2 and 12/8. Hard coding
this the long way with asm is 4 times faster than using div for
division. It doesn't seem to make so much of a differance how many
possible equations you decide to use either, unless you are talking
about hundreds of them.

#include <cstdlib>
#include <iostream>
#include <ctime>

using namespace std;

int main(int argc, char *argv[]){
time_t t1, t0;
double elapsed;
time(&t0); /* start time */
for(int cnt=0; cnt<2000000000; cnt++){
asm("mov $0x80, %ax\n\t"
"mov $0x02, %bx\n\t"
"cmp $0x04, %ax\n\t"
"cmp $0x02, %bx\n\t"
"je label1\n\t"
"cmp $0x08, %ax\n\t"
"cmp $0x02, %bx\n\t"
"je label2\n\t"
"cmp $0x10, %ax\n\t"
"cmp $0x02, %bx\n\t"
"je label3\n\t"
"cmp $0x20, %ax\n\t"
"cmp $0x02, %bx\n\t"
"je label4\n\t"
"cmp $0x40, %ax\n\t"
"cmp $0x02, %bx\n\t"
"je label5\n\t"
"cmp $0x80, %ax\n\t"
"cmp $0x02, %bx\n\t"
"je label6\n\t"
"label1:\n\t"
"mov $0x02, %ax\n\t"
"jmp end\n\t"
"label2:\n\t"
"mov $0x04, %ax\n\t"
"jmp end\n\t"
"label3:\n\t"
"mov $0x08, %ax\n\t"
"jmp end\n\t"
"label4:\n\t"
"mov $0x10, %ax\n\t"
"jmp end\n\t"
"label5:\n\t"
"mov $0x20, %ax\n\t"
"jmp end\n\t"
"label6:\n\t"
"mov $0x40, %ax\n\t"
"end:\n\t");
}
time(&t1);
elapsed = difftime(t1, t0);
cout<<"Time: "<<elapsed<<" seconds."<<endl;
time(&t0); /* start time */
for(int cnt=0; cnt<2000000000; cnt++){
asm("mov $0x80, %ax\n\t"
"mov $0x02, %bx\n\t"
"div %bx, %ax\n\t");
}
time(&t1);
elapsed = difftime(t1, t0);

cout<<"Time: "<<elapsed<<" seconds."<<endl;


system("PAUSE");
return EXIT_SUCCESS;
}
 
M

Mike Smith

This C++ program is an example of this kind of optimization. The lines
commented out preform the exact same function as the lines which
preform arithmetic on the variables, but the commented lines are much
faster.

The commented lines are faster because compare-and-branch is likely to
be faster if the code is cached, which for such a small example it most
likely will be. However, this only works because your "addition jump
table" is so short, since you're always adding the same constants. To
make this table large enough to add any arbitrary ints would be too
large to hold in *memory*, let alone the code cache.
 
J

Jerry Coffin

I asked the question, "how do you define arithmetic?", and when I came
to an answer I understood math in a new, much clearer way. I also
happened upon a method of arithmetic optimization that really speeds up
calculations on computers.

You may find it easier to understand, but I doubt that there's any
reasonable circumstance under which what you've shown really improves
speed. On a typical CPU, integer addition is already as fast as any
operation defined for the processor. That typically means one clock,
though in a few cases (e.g. the Pentium 4) it comes to only half a
clock (the Pentium 4 has a small part of the core operating at double
speed, so a single execution unit can produce 2 additions per clock).

One of the big considerations in designing hardware is the silicon
area, whihc is proportional to the number of gates required. For a
normal adder, the number of gates is approximately 2N where N is the
number of bits in a word (e.g. 32 for a 32-bit computer).

At least as I read it, your method would require gates proportional to
2^N instead. That limits the method to exceptionally small sizes --
e.g. a single adder built this way would use more silicon that planet
earth contains.
What I found in terms of computer programming, is that when I manually
assign values to variables I don't need to use the operators to do
arithmetic. What I like about doing it this way is it is faster.

What convinces you that this is faster? At best, I can see it hoping to
be the same speed, and under normal circumstances, it would be
somewhere between slightly and a drastically slower.
This C++ program is an example of this kind of optimization.
s/optimization/pessimization/g

The lines
commented out preform the exact same function as the lines which
preform arithmetic on the variables, but the commented lines are much
faster.

I seriously doubt they're really faster, and even if they were, you
haven't really shown much of anything. How about if you show us how
you'd implement even a slightly more general case, such as:

unsigned long total = 0;

for (unsigned i=0; i<100000; i++)
total += i;

Of course, this is still too trivial to prove _much_, but even so, I
suspect a working implementation will convince you that the approach
has more weaknesses than strengths.

Finally, I'd note that your method is really little more than a rather
convoluted method of implementing a table lookup. A much cleaner method
would be to just index into an actual table. This is pointless for
addition, but it can be worthwhile for things that are relatively slow
to calculate (e.g. for interactive graphics I've sometimes used small
tables of sine/cosine values).
 
P

Puppet_Sock

(e-mail address removed) wrote:
[stuff]

On June 6 you promised you were done with usenet.
Socks
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top