|
Yes, I have programmed background threads.
What's your point?
Thanks,
Della.
|
|
|
|
|
farnster wrote:
What's your point?
You should then have tried it with the case you are refering to and report any problem.
If you have never programmed a thread then you will need a startup code but having done it I see no reason why you should not try it first.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Paul, I bought the book "Advanced .NET Remoting" because of your review on Amazon, I'm only beginning to read it, and I just let you known that if I don't like the book, my reason to return it , will be that a fellow CPian played a trick on me
Cheers,Joao Vaz
And if your dream is to care for your family, to put food on the table, to provide them with an education and a good home, then maybe suffering through an endless, pointless, boring job will seem to have purpose. And you will realize how even a rock can change the world, simply by remaining obstinately stationary.-Shog9
Remember just because a good thing comes to an end, doesn't mean that the next one can't be better.-Chris Meech
|
|
|
|
|
I stand by my review and will write a new book for you if this does not make the grade
Anyway, welcome to the .NET Remoting - be prepared to answer my questions on the forum on .NET Remoting since I will be starting a project on this next 2 weeks.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
I want to write an MFC application that can be turned into the icon on task bar (like Norton Antivirus).
If it is Windows 9x/2000, the icon will appear next to the clocks at the right bottom of screen.
Thank you for your concern!
|
|
|
|
|
Please use the Visual C++ forum. This is MC++ forum.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
|
Can't remember
Anyway, we are trying to make sure any MC++ programmer here is satisfied and we cannot include non-MC++ stuff
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
If you see that it means that object could come from several sources. Use the required namespace to get the one you want. Read the build message (not the TODO) to get detailed information.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hi, we're going to develop an ANSI compliant C++ module and portablility is a major concern: We want to deploy this module to MS/UNIX/LINUX. We need a good ANSI compliant XML parser that supports at least DOM/XPATH/dynamic navigation.. any suggestion?
I presume I can load XML file via stdio and perform any subsequent manipulation using this XML parser..?
.NET offers very good tool but it's not portable.
norm
|
|
|
|
|
Hello Norm,
Please use the Visual C++ forum, this forum is mainly MC++.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
I thought of doing that actually. But I don't see how an ANSI C++ question is a better fit under VC++ category than under MC++.
Anyway...
Norm
|
|
|
|
|
You have everything having to do with C++ there, but with .NET here - that is the difference.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hi,
i like to save received data files (.pmj) from a scanner serially numbered on my disc (001.pmj, 002.pmj, ...) I know i must work with a loop and a variable, but it is too tricky for me.
Untill now i do the following:
// Save the file...
if (r)
{
CString fileName = "e:\\data\\001.pmj";
SavePMJStream(fileName);
}
Thanks for help, Mark
|
|
|
|
|
Please this is MC++ forum, try the Visual C++ forum for MFC stuff.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
BTW in advance I apologize for this super lengthy post! Any help would be GREATLY apreciated. I am aware that my codeing is a bit messed up but thats ok.. for now.. the main thing is that I figure out how to put all this to use properly while understanding why it works.
Ok everybody I hope I am not stepping out of line in posting this question on this forum. I'm a new member of the code project and I am new to programing in general, have started programming in c++ but my knowledge is and will be fairly limmited for a while.. I am trying to put to use what I have learned in a simple program but have come across a problem. Mind you it could just be that my brain is completely fried from digesting 300 pages of the book I am studying to learn c++ in 3 days (OUCH!)
the program is as follows In brackets () I have put my questions hope this doesn't confuse anybody.. dont worry I havent use () in the program itself yet.
<br />
#include <stdio.h><br />
#include <iostream.h><br />
#include <string.h><br />
int main(int nNumberOfArgs, char* pzargs[])<br />
{
Int response;<br />
cout << "Enter a question or comment to which jeeney may respond:';<br />
cin >> response;<br />
//Calculate statement or question input to result a<br />
//coresponding statement or question to output
(The problem I have is here.. I need to create an "if" statement example
"if" input responce is "Hello Jeeney" "then" Jeeney would respond useing
another sentence or question such as Ex: "Hello, how are you today?"
I'm not entirely sure how to do this as I seem to be learning ONLY useing numbers. I somewhat understand HOW it should work but am not very sure of the codeing used.)
( int factor; this part is confuseing as well. I am working with character strings rather then integers so wouldn't this be more apropriately put as "char factor" ? and that doesn't seem to make any sence either.
( factor = )
return 0;<br />
}
|
|
|
|
|
Hello Caden,
To get a better response you will need to property phase your question.
Anyway, this forum is for MC++, try using the Visual C++ forum.
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
OOPS! Go figure I'd mess up ... sorry!
|
|
|
|
|
Hi!
I am working on a function that returns an object initilized with some
specific values, like
<br />
__value struct MyStruct<br />
{<br />
public:<br />
MyStruct(int a, int b, int c)<br />
: a(in_a), b(in_b), c(in_c) {}<br />
<br />
static MyStruct One() { return MyStruct(1,1,1); }<br />
<br />
private:<br />
int a, b, c;<br />
};<br />
This is compiled to the following MSIL-code:
<br />
.method public static valuetype Cpp.MyStruct<br />
One() cil managed<br />
{<br />
.maxstack 4<br />
.locals (valuetype Cpp.MyStruct V_0)<br />
IL_0000: ldloca.s V_0<br />
IL_0002: initobj Cpp.MyStruct<br />
IL_0008: ldloca.s V_0<br />
IL_000a: ldc.i4.1<br />
IL_000b: ldc.i4.1<br />
IL_000c: ldc.i4.1<br />
IL_000d: call instance void Cpp.MyStruct::.ctor(int32,<br />
int32,<br />
int32)<br />
IL_0012: ldloca.s V_0<br />
IL_0014: ldobj Cpp.MyStruct<br />
IL_0019: ret<br />
}
I looked at IL_0002 and found a initobj. I tried to avoid initializing of
the members, so I defined an empty default c'tor:
MyStruct() {}
However, now my IL code expanded to:
<br />
.method public static valuetype Cpp.MyStruct<br />
One() cil managed<br />
{<br />
.maxstack 4<br />
.locals (valuetype Cpp.MyStruct V_0,<br />
valuetype Cpp.MyStruct V_1)<br />
IL_0000: ldloca.s V_1<br />
IL_0002: initobj Cpp.MyStruct<br />
IL_0008: ldloca.s V_1<br />
IL_000a: ldc.i4.1<br />
IL_000b: ldc.i4.1<br />
IL_000c: ldc.i4.1<br />
IL_000d: call instance void Cpp.MyStruct::.ctor(int32,<br />
int32,<br />
int32)<br />
IL_0012: ldloca.s V_0<br />
IL_0014: ldloca.s V_1<br />
IL_0016: cpobj Cpp.MyStruct<br />
IL_001b: ldloca.s V_0<br />
IL_001d: ldobj Cpp.MyStruct<br />
IL_0022: ret<br />
}
Which contains a cpobj and two local instances of MyStruct and therefore
seems to be even worse.
I wrote a similar struct in C# to compare compilation output:
<br />
public struct MyStruct<br />
{<br />
public MyStruct(int in_a, int in_b, int in_c)<br />
{<br />
a = in_a;<br />
b = in_b;<br />
c = in_c;<br />
}<br />
public static MyStruct One() { return new MyStruct(1, 1, 1); }<br />
int a, b, c;<br />
};<br />
This compiled to the following code:
<br />
.method public hidebysig static valuetype CSharp.MyStruct<br />
One() cil managed<br />
{<br />
.maxstack 8<br />
IL_0000: ldc.i4.1<br />
IL_0001: ldc.i4.1<br />
IL_0002: ldc.i4.1<br />
IL_0003: newobj instance void CSharp.MyStruct::.ctor(int32,<br />
int32,<br />
int32)<br />
IL_0008: ret<br />
}
Now I tested execution time and I am not really suprised: the the C++ struct
without default c'tor was about 30% slower than the C# version. The C++
Version with default c'tor even was 70% slower than the C# version.
Now I have two questions: first, is the C# version creating the object on
the heap or the stack?
And: how can I make the C++ version compile to the faster version?
Thanks in advance!
- Andre
|
|
|
|
|
Hello Andre,
VizOne wrote:
...is the C# version creating the object on
the heap or the stack?
As you suspected, the C# version is allocating on the heap, which is what the 'newobj' IL instruction normally does. So, the two pieces of code are not equivalent, and is partly why the instructions differ so.
The MC++ bit is dealing with a stack object, and even more importantly, is returning a copy of the object, not just a pointer (object reference in .Net lingo) to it. The 'ldobj' instruction verifies this, and I think a large part of the performance difference. Not only is the __value object initialised (initobj Cpp.MyStruct), but it's address is repeatedly pushed onto the stack (ldloca.s V_0) for various ops.
So the address of the static struct is loaded, it's initialised, the address is again loaded, constant params loaded, the ctor called, the object's address loaded yet again, then an entire copy made before returning. I can see why performance was bad.
However, I'm thinking the number of ops is not the most reliable way to gauge performance here. In particular, newobj does a lot for a single instruction, including runtime allocation on the GC heap, initialising, and then calling the ctor. Admittedly GC heap allocation is designed to be very fast, and nearly as fast as stack allocation, but the C# code does not make a copy. I suspect that's the biggest factor.
I'm curious if the code was optimised during compile, as that might make a significant difference. You have me digging deeper into this one, so I'll post back if I come up with anything more. I'll try making the MC++ and C# functions both return copies and pointers. Shame on you for stimulating my attrophied neurons! Interesting stuff.
Cheers
|
|
|
|
|
Jeff J wrote:
Shame on you for stimulating my attrophied neurons!
...and on you for coming out with something reasonable. I am still searching my references
Anyway, let us know the results of your research. MC++ is here to stay!!!
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Hello Paul,
Paul Selormey wrote:
MC++ is here to stay!!!
Yes it is! In fact, I'm counting on VS.Net 2003 making it a lot more popular. Looks like we'll be some of the few ahead of the game.
Cheers,
Jeff
|
|
|
|
|
Hello Andre (and Paul),
I played with the code you posted and some other stuff, but could not find a way to optimise the MC++ MSIL any further, but that may not be as much of a problem as we first thought. BTW, I can now see your MSIL was taken from optimised compiles.
Regarding your earlier question of whether the C# struct was being allocated on the stack or on the heap, I think I judged too quickly based on the MSIL. CIL documentation does not say much about newobj being applied to value types, however it "can" be used to allocate on the stack. It also says that it is rarely done this way. The blanks leave questions, but my guess is that newobj is itself optimised to return value types/structs as efficiently as possible, and in this unusual case, not on the heap. CLI instructions are not like low-level assembler op-codes, but more like convenient groups of instructions (actually, so are some op-codes).
Frustrated with MSIL, I moved to assembler, and found the following:
static MCppStruct GetStack() | public static CshStruct GetNew()
{ return MCppStruct(1,2,3); } | { return new CshStruct(1, 2, 3); }
-------------------------------------------------------------------------------------
00 push ebp | 00 push ebp
01 mov ebp,esp | 01 mov ebp,esp
03 sub esp,10h | 03 sub esp,10h
06 push edi | 06 push edi
07 push esi | 07 push esi
08 push ebx | 08 push ebx
09 <FONT color="green">mov ebx,ecx</FONT> |
0b <FONT color=blue>lea edi,[ebp-10h]</FONT> |
0e xor eax,eax | 09 xor eax,eax
10 <FONT color=blue>stos dword ptr [edi]</FONT> | 0b <FONT color=blue>mov dword ptr [ebp-10h],eax</FONT>
11 <FONT color=blue>stos dword ptr [edi]</FONT> | 0e <FONT color=blue>mov dword ptr [ebp-0Ch],eax</FONT>
12 <FONT color=blue>stos dword ptr [edi]</FONT> | 11 <FONT color=blue>mov dword ptr [ebp-8],eax</FONT>
| 14 <FONT color="green">mov ebx,ecx</FONT>
13 push 2 | 16 push 2
15 push 3 | 18 push 3
17 lea ecx,[ebp-10h] | 1a lea ecx,[ebp-10h]
1a mov edx,1 | 1d mov edx,1
1f call dword ptr ds:[00825230h] | 22 call dword ptr ds:[008151F0h]
25 mov edi,ebx | 28 mov edi,ebx
27 lea esi,[ebp-10h] | 2a lea esi,[ebp-10h]
2a movs dword ptr [edi],dword ptr [esi] | 2d movs dword ptr [edi],dword ptr [esi]
2b movs dword ptr [edi],dword ptr [esi] | 2e movs dword ptr [edi],dword ptr [esi]
2c movs dword ptr [edi],dword ptr [esi] | 2f movs dword ptr [edi],dword ptr [esi]
2d pop ebx | 30 pop ebx
2e pop esi | 31 pop esi
2f pop edi | 32 pop edi
30 mov esp,ebp | 33 mov esp,ebp
32 pop ebp | 35 pop ebp
33 ret | 36 ret
-------------------------------------------------------------------------------------
Most instructions are the same, except for those in blue. For the C# code, the JIT individually moves zero (in EAX) into the ints, whereas the MC++ stuff translates to using store-string (which requires loading the first address into EDI before the calls). They accomplish the same thing, and I don't recall that stos is slower than mov, so I'm stumped here. Best I can tell, performance should be about the same. The constructors were exactly the same. I don't see heap alloc here. So much for reading MSIL.
Is it possible that there is a difference in the code you used to test the performance? Maybe forgot to switch the MC++ to release mode as I originally did? Who knows, maybe the JIT settings used when debuggin' C# code, hides further optimisations done outside the IDE. I am assuming the disassembly view is accurate. Anyway, this has been a lesson for me that different byte codes can produce similar asm. Sorry for the short post
Regards,
Jeff
|
|
|
|
|
Hello Jeff,
Thanks for the great work you are doing. The assembler results is interesting.
I now wish Andre could post his test projects so that we could examine them too.
Anyway, keep it up. I now have to take my IL lessons serious
Best regards,
Paul.
Jesus Christ is LOVE! Please tell somebody.
|
|
|
|
|
Whoops, it seems I did not get an e-mail notification. Something's going on in here, I see.
I'm short on time right now, so I cannot post the test code (maybe it was a test way too naiv at all). I'll post it when I have a little more time.
Thanks already for the interesting research, Jeff!
- Andre
|
|
|
|
|