|
ok, we have a misunderstanding here: i compared the results with original post, not with suhredayan's solution which i didn't tested because of comments below it. i never said that my solution is the fastest one, i said that it is fastest of the three i showed.
it would be extremely stupid to say that something is fastest, everything can be optimized.
another thing is that dissasembly for my function is larger but not that much as it seems, because suhredayan's version is missing prolog and epilog code, which is automatically added by the compiler. when you compare code which is really generated, suhredayan's version is only 2 instructions shorter (16:14).
however, i did some test with following test app:
<code>
#include "stdafx.h"
#include <wtypes.h>
#define ITERATIONS 300000000
inline void UltraSwap2( LONG* a, LONG* b )
{
LONG t = *b;
*b = *a;
*a = t;
}
inline void UltraSwap4( LONG* a, LONG* b )
{
__asm mov eax, dword ptr [a]
__asm mov ebx, dword ptr [b]
__asm mov dword ptr [a], ebx
__asm mov dword ptr [b], eax
}
int main(int argc, char* argv[])
{
long t;
long a = 111111111;
long b = 222222222;
char txt[1024];
{
t = GetTickCount();
for(long i = 0; i < ITERATIONS; ++i)
{
UltraSwap2(&a, &b);
}
t = GetTickCount() - t;
sprintf(txt, "UltraSwap2: %ld iterations done in %ld ms\n", ITERATIONS, t);
printf(txt);
}
{
t = GetTickCount();
for(long i = 0; i < ITERATIONS; ++i)
{
UltraSwap4(&a, &b);
}
t = GetTickCount() - t;
sprintf(txt, "UltraSwap4: %ld iterations done in %ld ms\n", ITERATIONS, t);
printf(txt);
}
return 0;
}
</code>
here are my results (3 runs for each version):
release build, non optimized:
D:\test\Release>test.exe
UltraSwap2: 300000000 iterations done in 3024 ms
UltraSwap4: 300000000 iterations done in 4376 ms
D:\test\Release>test.exe
UltraSwap2: 300000000 iterations done in 4387 ms
UltraSwap4: 300000000 iterations done in 4366 ms
D:\test\Release>test.exe
UltraSwap2: 300000000 iterations done in 4376 ms
UltraSwap4: 300000000 iterations done in 4537 ms
release build, optimized for speed:
D:\test\Release>test.exe
UltraSwap2: 300000000 iterations done in 201 ms
UltraSwap4: 300000000 iterations done in 771 ms
D:\test\Release>test.exe
UltraSwap2: 300000000 iterations done in 210 ms
UltraSwap4: 300000000 iterations done in 761 ms
D:\test\Release>test.exe
UltraSwap2: 300000000 iterations done in 211 ms
UltraSwap4: 300000000 iterations done in 771 ms
in non optimized version, results are similar. but it seems that suhredayan's version is much harder to optimize by compiler, so in optimized version it is much slower. i believe that reason for this is that compiler cannot reuse the registers to best-fit the other optimizations, resulting in significantly larger code. this means that it is hard to outperform the compiler's optimization and it should be done only in extreme situations.
|
|
|
|
|
Hey, I found something interesting while playing with my test application, I did a modification to UltraSwap2 and made this one :
</code>_inline PVOID UltraSwap3( LONG* a, LONG* b )
{
__asm mov eax, dword ptr [a]
*a = *b;
__asm mov dword ptr [b], eax
}</code>
It's not quite elegant for a "supposed" assembly but look at the result in Release mode :
UltraSwap2 after 1 loops : 0.004190476 ms
UltraSwap2 after 1000 loops : 0.016761902 ms
UltraSwap2 after 10000 loops : 0.138285693 ms
UltraSwap2 after 1000000 loops : 13.729674098 ms
UltraSwap2 after 10000000 loops : 218.611242878 ms
-------------------------------------
UltraSwap3 after 1 loops : 0.003352380 ms
UltraSwap3 after 1000 loops : 0.013409522 ms
UltraSwap3 after 10000 loops : 0.092190462 ms
UltraSwap3 after 1000000 loops : 8.895541502 ms
UltraSwap3 after 10000000 loops : 128.132170951 ms
It's a lot more faster for long loops!!
Stef
Progamming looks like taking drugs...
I think I did an overdose.
|
|
|
|
|
yes, almost every solution can be made even better, but this solution doesn't work correctly, it stores the address of a into eax, then sets a to value of b, and then sets b to value now stored in a which results in a and b being equal.
if you have a chance, take a look at michael abrash's book "zen of code optimization", it will show you many neat tricks.
understanding/knowing assembly can only make you a better developer, so this is the right way to go.
|
|
|
|
|
Oups!!
I've tested every code in debug to be sure that everything was swapped properly but forgot this one !
Thanks Zdeslav! For sure, I will look for the book you're talking about.
I ran my test program with swap codes exactly identical to the ones you tested yourself and it gives me always the same result, the assembly code is always still faster. I don't understand. Maybe it depend on the way it is compiled and on which CPU it is ran...
I use MS Visual C++ 6.0
Compiler version : MS 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Linker version : MS Incremental Linker Version 6.00.8168
My CPU is : Intel Pentium III, 450MHz
SDK installed : MS SDK for WinXP SP2
My project settings are the base one for an MFC dialog-based application.
Also, every loops are called within a worker thread sets with normal priority.
Progamming looks like taking drugs...
I think I did an overdose.
|
|
|
|
|
Forget my last post Zdeslav!
I found what's going wrong, I missed to place the "inline" instruction in my function header!! Sorry.
Ok, now I go sleep, I think I need it! Ha ha ha!
Thanks for help!
Progamming looks like taking drugs...
I think I did an overdose.
|
|
|
|
|
Thanks everyone!
I think I will use the UltraSwap2 solution from Zdeslav, since it is more faster than all the other ones. It was my mistake to think that it should be faster to do it in assembly code.
But if I refer at my wishes to learn some assembly code, the suhredayan solution is what I was looking for.
I used to code on some industrial programmable controllers a long time ago and it was in assembly code. But both syntax and function names wasn't the same.
Great help guys!
Stef
Progamming looks like taking drugs...
I think I did an overdose.
|
|
|
|
|
Before putting forward my question, i'd like to show what i want to achieve: First, i will make a directory in which all of the secrete information are saved, of course, only the authorized users can access this directory, and also, in order to defend the secrete information, for example, the source code of a firm, it's necessary to prevent these users from disclosing the secrete information in any way, for instanse, copy a file in this director to another directory, or open a file with one application program, and then save as another file to other place. So my question is how to achieve this goal, please give me some ideas. Thank you very much!
|
|
|
|
|
zymoonstone wrote:
of course, only the authorized users can access this directory
Once you give the access, then hope they will not disclose it.
suhredayan There is no spoon.
|
|
|
|
|
Do you mean it is impossible?
|
|
|
|
|
How can i determine programmatically whether i am connected to the internet or not?
|
|
|
|
|
|
See here.
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
|
I want to change the color of title bar of my dialog box/sdi/mdi window. Can any body tell me what is the most simple way to do it "Programmatically"(means not using a separate class for this purpose)?
|
|
|
|
|
This is a FormView application,and a list control is used.I want to fix first four columns of the list ctrl fixed and all other columns to allow scrolling.
Please help me to solve this..
thanks in advance.
|
|
|
|
|
Im trying to pass the values of an object, plus a few other numbers. TEXT OUTPUT ATTACHED BELOW Im sure it's something Im doing wrong.
The function:
void dataOut(std::string foodName, int Calor, double wtr, double prt,<br />
double fat,double carb,double fib,double vita,double vitb,double vitc,double calci)
...followed by some commands for sending values to a text file. Im using std::ofstream and std::fstream .(working)
The function call:
dataOut(breadobject.strFileName,breadobject.intCalor,<br />
2.2,0.0,breadobject.dblFat,breadobject.dblCarb, breadobject.dblFiber,0.0,0.0,0.0,0.0);
The text output to the file:
Food: White Slice
Calories: 0
Water (oz): 2.2
Protein: 0
Fat: -9.25596e+061
Carbohydrates: -9.25596e+061
Fiber: -9.25596e+061
Vitamin A: 0
Vitamin B: 0
Vitamin C: 0
Calcium: 0
My observations:
The name of the food (breadobject.strFileName) is correctly being received by the function, but the numeric values (i.e. breadobject.intCalor, breadobject.dblFat) are not. Any explicit double values that I send are coming through ok too.
Ok. This should be an easy one for you geniuses!
Thanks in advance.
Travis
|
|
|
|
|
It's difficult to see what the problem might be without seeing more of your source code. Anyway, here is a short program which does something like what you're after (I think).
/////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void dataOut(string foodName, int Calor, double wtr)
{
ofstream out("MyFile");
out << foodName << endl << Calor << endl << wtr;
}
void dataIn(string foodName, int Calor, double wtr)
{
ifstream in ("MyFile");
in >> foodName >> Calor >> wtr;
cout << "Food: " << foodName << endl<<
"Calories: " << Calor << endl <<
"Wtr: " << wtr << endl;
}
class FileData
{
public:
string strFood;
int intCalor;
double dblFat;
FileData() : strFood("Cakes"), intCalor(1000),
dblFat(2.2222){};
};
int main()
{
FileData breadobject;
dataOut(breadobject.strFood, breadobject.intCalor,
breadobject.dblFat);
dataIn(breadobject.strFood, breadobject.intCalor,
breadobject.dblFat);
return 0;
}
//////////////////////////////////////////////
Hope this helps,
David
|
|
|
|
|
Thank you very much for the response. Unfortunately, my problem is unchanged.
Sorry if my question is vague.
To clarify: I only need to save these values to the file.
It is reassurring to see that you are using the same method that I have for passing the values to the ofstream. Notice that portion in the code below.
The function definition and function call (with arguments) are as previously posted and as you have described.
Now I am beginning to think that the problem does not exist in the
function call --> function --> file open and output.
Rather, I am beginning to think the problem lies in the:
assigning values --> function call --> function
Please, take a look at the way I am assigning the values prior to handing them to the function call as arguments.
-snip-
//from bread.h
class Bread <br />
{<br />
public:<br />
<br />
void setValues(double fat,double carb,int calor,double fiber);<br />
<br />
std::string strFileName;<br />
double dblFat;<br />
double dblCarb;<br />
double dblFiber;<br />
int intCalor;<br />
};
//from Bread.cpp
<br />
void dataOut(std::string foodName, int Calor, double wtr, double prt, double fat,double carb,double fib,double vita,double vitb, double vitc, double calci)<br />
{<br />
std::fstream<br />
appendFile("Tally.txt");<br />
<br />
<br />
if(!appendFile.is_open())<br />
{<br />
std::ofstream<br />
outputFile("Tally.txt");<br />
<br />
if(!outputFile.is_open())<br />
{<br />
std::cerr << "\nNot enough memory to create file\n";<br />
exit(1);<br />
}<br />
else<br />
{<br />
outputFile << << "\n\nFood: "<< foodName << "\n"<br />
<< "Calories: "<< Calor << "\n"<br />
<< "Water (oz): "<< wtr << "\n"<br />
<< "Protein: "<< prt << "\n"<br />
<< "Fat: "<< fat << "\n"<br />
<< "Carbohydrates: "<< carb << "\n"<br />
<< "Fiber: "<< fib << "\n"<br />
<< "Vitamin A: "<< vita << "\n"<br />
<< "Vitamin B: "<< vitb << "\n"<br />
<< "Vitamin C: "<< vitc << "\n"<br />
<< "Calcium: "<< calci << "\n";<br />
}<br />
}<br />
else<br />
{<br />
appendFile.seekp(0,std::ios::end);
<br />
appendFile << "\n\nFood: "<< foodName << "\n"<br />
<< "Calories: "<< Calor << "\n"<br />
<< "Water (oz): "<< wtr << "\n"<br />
<< "Protein: "<< prt << "\n"<br />
<< "Fat: "<< fat << "\n"<br />
<< "Carbohydrates: "<< carb << "\n"<br />
<< "Fiber: "<< fib << "\n"<br />
<< "Vitamin A: "<< vita << "\n"<br />
<< "Vitamin B: "<< vitb << "\n"<br />
<< "Vitamin C: "<< vitc << "\n"<br />
<< "Calcium: "<< calci << "\n";<br />
}<br />
}<br />
<br />
int main()<br />
{<br />
breadobject.setValues( 1.1 , 11.4 , 60 , 0.9 );<br />
breadobject.strFileName="White Slice";<br />
<br />
dataOut(breadobject.strFileName, breadobject.intCalor, 2.2, 0.0, breadobject.dblFat, breadobject.dblCarb, breadobject.dblFiber, 0.0, 0.0, 0.0, 0.0); <br />
<br />
return 0;<br />
}
WHEW!
Travis
|
|
|
|
|
Hi Travis,
You asked me to check the way you're assigning values
prior to sending them to the function call as arguements. I assume you are doing that in the setValues function member of Bread . Regrettably I see the declaration of setValues but not its definition so I can't help you there.
What I'd like you to do for me is to cut your code back to pretty much the smallest amount that succesfully compiles and demononstrates your problem, and post that complete code for me to compile and debug. I reckon that will be the fastest way of getting to the bottom of this.
Cheers,
David
|
|
|
|
|
Now Im getting SOMETHING anyway...
I put an amperstand in front of the calling argument like so:
SendThisInfoToTextFile( yada.yada, &yada.yada);
ANd I placed an asterisk at the receiving end:
SendThisInfoToTextFile( string yada1, int* yada2 ) {...send stuff to text file...}
now, my text file is receiving this:
CorrectYada1 <---correct output on line 1
0012EF44 <---Looks like the address of ...umm...Yada2
New theory: ofstream is for strings and not ints or doubles
feedback please?
If you check the posting times, you will see that I have been working on this all night.
must ... keep eyes... open ...
Travis
|
|
|
|
|
Hi Travis
I have big doubts about your new theory (ofstream is for strings and not ints or doubles). Streams should handle all data types. In the code I provided to you, streams handled string, int and double data types properly - both for storing to a file and reading it back.
You are right about 0012EF44 being the address of something. I would expect this to see this though if you stream the address of variables or pointers to variables to a file.
Once again, see if you could post a small amount of code which demonstrates your problem and is complete
enough to compile, and I'll check it for you.
Cheers,
David
|
|
|
|
|
Hi Travis,
I compiled your code, (after inventing a few missing bits) and it works fine for me. Your definition of setValues should look like this.
void Bread::setValues(double fat,double carb,int calor,double fiber)
{
dblFat = fat;
dblCarb = carb;
intCalor = calor;
dblFiber = fiber;
}
The contents of Tally.txt looks like this...
Food: White Slice<br />
Calories: 60<br />
Water (oz): 2.2<br />
Protein: 0<br />
Fat: 1.1<br />
Carbohydrates: 11.4<br />
Fiber: 0.9<br />
Vitamin A: 0<br />
Vitamin B: 0<br />
Vitamin C: 0<br />
Calcium: 0
One possible explanation for your problem....
Did you declare dblFat, dblCarb, intCalor and dblFiber as local variables inside setValues . If you did, you will be setting the values of local variables, and not member variables of Bread . The member variables of Bread would remain undefined and you would indeed get garbage if you streamed them to a file.
In any case, it is a good idea to set reasonable default values for member variables of a class in its constructor to avoid this sort of trap.
Cheers
David
|
|
|
|
|
I inserted your code and it works now.
Im still waking up. Il give some details shortly.
Travis
|
|
|
|
|
Your version...
void Bread::setValues(double fat,double carb,int calor,double fiber)
{
dblFat = fat;
dblCarb = carb;
intCalor = calor;
dblFiber = fiber;
}
My old version...
void Bread::setValues(double fat,double carb,int calor,double fiber)
{
double
tmpfat = fat,
tmpcrb = carb,
tmpfbr = fiber;
int
tmpclr = calor;
}
... Sad is the day when a man realizes that he is an idiot!
Thank you so much for helping me to get this working. My program should be completed on time.
Travis
|
|
|
|
|
Hi Travis,
I'm happy to help, and I'm glad your code is working now.
One final suggestion if I may.
Its a little unusual in C++ to create a class object and then set it's values. Normally you would use a constructor to either assign values when the object is created, or set values to a sensible default. That way, whenever the object is used, it's member variables are guaranteed to have assigned values, and the problem you experienced would never arise.
In your case, your code could look something like this.
class Bread
{
public:
Bread(double fat,double carb,int calor,double fiber,
std::string filename);
void setValues(double fat,double carb,int calor,double
fiber);
std::string strFileName;
double dblFat;
double dblCarb;
double dblFiber;
int intCalor;
};
Bread.cpp might look something like this....
Bread::Bread(double fat,double carb,int calor,double
fiber,std::string filename)
{
dblFat = fat;
dblCarb = carb;
intCalor = calor;
dblFiber = fiber;
strFileName = filename;
}
int main()
{
Bread breadobject(1.1, 11.4, 60, 0.9, "White Slice");
dataOut(breadobject.strFileName, breadobject.intCalor,
2.2, 0.0, breadobject.dblFat, breadobject.dblCarb,
breadobject.dblFiber, 0.0, 0.0, 0.0, 0.0);
return 0;
}
Its your code of course, and this approach might not suite your purposes. Its all up to you.
Cheers
Dave
|
|
|
|
|