Author |
Message |
Jonathan Ros #1 / 15
|
 Byte Code; Direct Style
The following code sample is a GNU compliant byte-code run loop example. Unfortunately I can't get the {*filter*}y thing to compile in VC.Net or VC++ 6.0. How can I adapt this to work for VC.NET or preferably ANSI C++; the most important part being getting the label addresses. Note: I understand I can use a switch statement, but I really don't want nor need a check to make sure it's within bounds. If there's a way to define a switch statement without the bounds checking I'm all ears. #define NEXT goto **ip++ main() { static void *prog[] = {&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&loop}; void **ip=prog; int count = 10000000; next: NEXT; loop: if (count>0) { count--; ip=prog; NEXT; } Quote: }
Off Subject: Anyone know where I can get a nice Itanium/Hammer simulator, if I can compile XP 64 while in 32-bit windows, and if XP 64 will support the Hammer Architecture and if it does will VC.NET be able to compile 64-bit code for it? If so I have some benchmarks I'm working on that I'd love to try and test on those 64-bit chips, specifically the Claw Hammer if it's going to be as reasonably priced as we've been led to believe. --Jonathan Ross, Mark Ross & Co., VB Programmer // If you need to send me e-mail remove all numbers and capital letters from the e-mail listed.
|
Sun, 01 Aug 2004 02:09:25 GMT |
|
 |
Jonathan Caves [MSFT #2 / 15
|
 Byte Code; Direct Style
I don't know what language this is -- but it is not C or C++ as I know it. There is no way in C or C++ to take the address of a label: the only way I could think of doing this would be using assembler -- but that would not be very protable. -- Jonathan Caves Microsoft Corporation This posting is provided "AS IS" with no warranties, and confers no rights.
Quote: > The following code sample is a GNU compliant byte-code run loop example. > Unfortunately I can't get the {*filter*}y thing to compile in VC.NET or VC++ 6.0. > How can I adapt this to work for VC.NET or preferably ANSI C++; the most > important part being getting the label addresses. > Note: I understand I can use a switch statement, but I really don't want nor > need a check to make sure it's within bounds. If there's a way to define a > switch statement without the bounds checking I'm all ears. > #define NEXT goto **ip++ > main() > { > static void *prog[] = > {&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&loop}; > void **ip=prog; > int count = 10000000; > next: > NEXT; > loop: > if (count>0) { > count--; > ip=prog; > NEXT; > } > } > Off Subject: Anyone know where I can get a nice Itanium/Hammer simulator, > if I can compile XP 64 while in 32-bit windows, and if XP 64 will support > the Hammer Architecture and if it does will VC.NET be able to compile 64-bit > code for it? If so I have some benchmarks I'm working on that I'd love to > try and test on those 64-bit chips, specifically the Claw Hammer if it's > going to be as reasonably priced as we've been led to believe. > --Jonathan Ross, Mark Ross & Co., VB Programmer > // If you need to send me e-mail remove all numbers and capital letters from > the e-mail listed.
|
Mon, 02 Aug 2004 08:29:40 GMT |
|
 |
Jonathan Ros #3 / 15
|
 Byte Code; Direct Style
Actually GNU added that &&label bit a few years back. I went ahead and tried to compile the sample with gcc as a c file and it compiled without a complaint; running it on the other hand was another matter. However, to simplify things here's an example I got to work in gcc as a c source file. Are you sure there's no way to do this in VC++? #include <stdio.h> #define NEXT goto *ip++ main() { static void *prog[] = {&&cool,&¬cool}; //void **ip=prog; //int count = 1; goto *prog[0]; notcool: printf("Not Cool\n"); exit(0); cool: printf("Cool\n"); exit(0); Quote: }
The output when compiled and ran was, of course, "Cool". The following did however work in VC++ #include <iostream> void main() { __asm jmp mylabel; std::cout << "didn't work" << std::endl; return; mylabel: std::cout << "worked" << std::endl; return; Quote: }
If I have to I'll just swap a definition depending on what platform I have set for compile, not like my GUI stuff is all that ANSI anyway :) But I would prefer an ANSI solution if there is one, and that's what I was wondering, if there was an ANSI solution. --Jonathan Ross, Mark Ross & Co, Software R&D
Quote: > I don't know what language this is -- but it is not C or C++ as I know it. > There is no way in C or C++ to take the address of a label: the only way I > could think of doing this would be using assembler -- but that would not be > very protable. > -- > Jonathan Caves > Microsoft Corporation > This posting is provided "AS IS" with no warranties, and confers no
rights.
|
Mon, 02 Aug 2004 06:36:38 GMT |
|
 |
Jonathan Ros #4 / 15
|
 Byte Code; Direct Style
Errrr, ignore that second example of the jmp instruction. <blinks> I'm going to blame it on programming for 18 straight hours [ minus a 15 minute lunch break ]. Just stick to the part about is there an ANSI C or C++ way to do the first example.
Quote: > Actually GNU added that &&label bit a few years back. I went ahead and > tried to compile the sample with gcc as a c file and it compiled without a > complaint; running it on the other hand was another matter. However, to > simplify things here's an example I got to work in gcc as a c source file. > Are you sure there's no way to do this in VC++? > #include <stdio.h> > #define NEXT goto *ip++ > main() > { > static void *prog[] = {&&cool,&¬cool}; > //void **ip=prog; > //int count = 1; > goto *prog[0]; > notcool: > printf("Not Cool\n"); > exit(0); > cool: > printf("Cool\n"); > exit(0); > } > The output when compiled and ran was, of course, "Cool". The following > did however work in VC++ > #include <iostream> > void main() > { > __asm jmp mylabel; > std::cout << "didn't work" << std::endl; > return; > mylabel: > std::cout << "worked" << std::endl; > return; > }
|
Mon, 02 Aug 2004 06:43:29 GMT |
|
 |
Greg Come #5 / 15
|
 Byte Code; Direct Style
Quote:
>> The following code sample is a GNU compliant byte-code run loop >example. >> Unfortunately I can't get the {*filter*}y thing to compile in VC.NET or VC++ >6.0. >> How can I adapt this to work for VC.NET or preferably ANSI C++; the most >> important part being getting the label addresses. >> Note: I understand I can use a switch statement, but I really don't want >nor >> need a check to make sure it's within bounds. If there's a way to define >a >> switch statement without the bounds checking I'm all ears. >> #define NEXT goto **ip++ >> main() >> { >> static void *prog[] = >> {&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&loop}; >> void **ip=prog; >> int count = 10000000; >> next: >> NEXT; >> loop: >> if (count>0) { >> count--; >> ip=prog; >> NEXT; >> } >> } >I don't know what language this is -- but it is not C or C++ as I know it. >There is no way in C or C++ to take the address of a label: the only way I >could think of doing this would be using assembler -- but that would not be >very protable.
Right, this is a gcc'ism. With the 4.3 release of Comeau we'll support this as an extension, along with 'goto *p;', but I agree one should not expect this for portable code. So to adapt it for Standard C++ you'll need to perhaps use pointers to function, or a switch statement or something. -- Greg Comeau GA BETA:4+ New Windows Backends PLUS 'export' beta online! Comeau C/C++ ONLINE ==> http://www.*-*-*.com/ World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90. Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
|
Mon, 02 Aug 2004 23:20:29 GMT |
|
 |
Greg Come #6 / 15
|
 Byte Code; Direct Style
Quote:
>>> #define NEXT goto **ip++ >>> main() >>> { >>> static void *prog[] = >>> {&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&loop}; >>> void **ip=prog; >>> int count = 10000000; >>> next: >>> NEXT; >>> loop: >>> if (count>0) { >>> count--; >>> ip=prog; >>> NEXT; >>> } >>> } >>I don't know what language this is -- but it is not C or C++ as I know it. >>There is no way in C or C++ to take the address of a label: the only way I >>could think of doing this would be using assembler -- but that would not be >>very protable. >Right, this is a gcc'ism. With the 4.3 release of Comeau we'll support >this as an extension, along with 'goto *p;', but I agree one should >not expect this for portable code. So to adapt it for Standard C++ >you'll need to perhaps use pointers to function, or a switch statement >or something.
BTW, if I'm not mistaken, your code seems equivalent to this: int main() { int count = 10000000; do { for (int next = 0; next < 9; next++) ; } while (count-- > 0); return 0; Quote: }
or for that matter just use 90000000L with one loop. -- Greg Comeau GA BETA:4+ New Windows Backends PLUS 'export' beta online! Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90. Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
|
Tue, 03 Aug 2004 01:41:01 GMT |
|
 |
Jonathan Ros #7 / 15
|
 Byte Code; Direct Style
When optimized down, yes, you're absolutely correct. However, I was simply trying to do some benchmarks to decide what form of byte code interpreter run structure would work best on different platforms. I may not have made it clear but I'm trying to design a Direct Calling interpreter, which may also be called a tail call interpreter (I'm not positive). Also, I tried to use the inline assembly of VC++ to load a label into a register, it did not work. At this point I'm concerned about my code being compliable in both gcc and VC++, but I would be willing to define a few assembly macros and switch them at compile time for the sake of speed. So with the goal of jumping to different areas in the function using an index to an array of code positions as opcodes I have two choices. The first is using a switch statement, which I do not like since compilers generally insert code to insure the variable is within bounds [ If I use an unsigned value for the switch will VC++ only check to make sure the opcode is <= the upper bound? ]. The second is the direct style which basically means that instead of having a break at the end of an opcode's code there is code that will move it directly to the next opcode in line. Here's a simple switch case example that I did get to work successfully in VC++. void switch_type() { static int prog[] = {0,0,0,0,0,0,0,0,0,1}; int *ip=prog; int count = 10000000; unsigned int nop = 0; for (;;) { switch (*ip++) { case 0: nop++; break; case 1: if (--count) { ip=prog; break; }else return; } } Quote: }
Remember that direct or tail style is different from switch style byte code in that instead of returning to the beginning of the switch statement, each opcode's native code goes straight to the next opcode in line instead of going back to another position and then re-entering. In other words, there's no nesting. What I want to achieve is a direct calling example I can use in my benchmark that will work in VC++ and GCC that has no bound checking. While I have no doubt that VC++ is an exceptionally smart compiler and may even generate assembly that does do direct calling when all the optimizations for speed are on (after all you're really just indexing an array for a switch anyway, where you index it from isn't all that important) my worry is two fold. First off, gcc may not be this smart and I'd like my code to be as static as possible. And secondly, there's still a very high if not 100% chance VC++ is still going to implement bound checking which is completely unnecessary as the opcode generation will be handled by an assembler which itself is used by a compiler in the finished product. As I said, I am not opposed to swapping a few macro definitions so long as the general structure is the same for both ports of the code. So my question to anyone who can answer is how do I get the offset of a position of code; the value of a label, and how do I then use that value, stored in memory, to jump to the portion of the code I want? As for the using Comeau the idea is starting to look very attractive for other reasons as well. I had planned to use non-fixed length arrays as masks for each code segment. The idea was to have a structure with some header, multi-threaded, etc. basic information in the front and an empty array at the bottom. I would then malloc whatever size code I need and use one of these structures as the type of a pointer to that malloced area. This would mean that the function wouldn't require an even deeper level pointer to the code and would save sizeof(pointer) space in the function as a bonus. While that does compile in VC++, it only compiles while Microsoft extensions are enabled (I'm writing my test code in VC++ 6.0, I'm waiting for my recently purchased MSDN Developer CustomerID to kick in). My concerns however are that one of the biggest reasons I choose to develop this project in Windows first instead of a Unix flavor or on a Mac (although Unix/Linux/Solaris x86 is my main target) is that IDE for VC.NET is just so extraordinary [ plus you just _HAVE_ to love the documentation and help ]. It also doesn't hurt that VC++ is such a smart optimizer, but that's just why I decided to actually compile the Windows final version in VC++, not why I'm developing in it. I looked at the Comeau site and I must admit I didn't quite fully grasp the concept of what it is. From my understanding it's basically the top layer of a compiler, it compiles into the middle code of another compiler, and then lets that compiler compile native code from it's own middle language. What concerns me is of course that I noticed Comeau is text prompt based system, and I heard no mention of it being an IDE. To me this is extraordinarily important and why I choose VC.NET in the first place. So my question to you is how could I leverage the IDE of VC.NET, the compiler of Comeau, and the middle language to native code abilities of VC.NET and GCC without making this project more difficult than it already is? --Jonathan Ross // To send me e-mail remove all capital letters and numbers from my e-mail address.
Quote:
> >>> #define NEXT goto **ip++ > >>> main() > >>> { > >>> static void *prog[] =
{&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&loop}; Quote: > >>> void **ip=prog; > >>> int count = 10000000; > >>> next: > >>> NEXT; > >>> loop: > >>> if (count>0) { > >>> count--; > >>> ip=prog; > >>> NEXT; > >>> } > >>> } > >>I don't know what language this is -- but it is not C or C++ as I know it. > >>There is no way in C or C++ to take the address of a label: the only way I > >>could think of doing this would be using assembler -- but that would not be > >>very protable. > >Right, this is a gcc'ism. With the 4.3 release of Comeau we'll support > >this as an extension, along with 'goto *p;', but I agree one should > >not expect this for portable code. So to adapt it for Standard C++ > >you'll need to perhaps use pointers to function, or a switch statement > >or something. > BTW, if I'm not mistaken, your code seems equivalent to this: > int main() > { > int count = 10000000; > do { > for (int next = 0; next < 9; next++) > ; > } while (count-- > 0); > return 0; > } > or for that matter just use 90000000L with one loop. > -- > Greg Comeau GA BETA:4+ New Windows Backends PLUS 'export' beta online! > Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout > World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90. > Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
|
Mon, 02 Aug 2004 23:04:19 GMT |
|
 |
Jonathan Caves [MSFT #8 / 15
|
 Byte Code; Direct Style
Jonathan: I not sure if I fully understand your concern about the Visual C++ compiler bounds-checking a switch statement. I do not believe that any C++ compiler will bounds check the expression in a switch-statement. If there is not a case label that corresponds to the value of the expression then the compiler will choose the default label, or if there is not a default label, it will just skip the body of the switch-statement. -- Jonathan Caves Microsoft Corporation This posting is provided "AS IS" with no warranties, and confers no rights.
Quote: > When optimized down, yes, you're absolutely correct. However, I was > simply trying to do some benchmarks to decide what form of byte code > interpreter run structure would work best on different platforms. I may not > have made it clear but I'm trying to design a Direct Calling interpreter, > which may also be called a tail call interpreter (I'm not positive). > Also, I tried to use the inline assembly of VC++ to load a label into a > register, it did not work. At this point I'm concerned about my code being > compliable in both gcc and VC++, but I would be willing to define a few > assembly macros and switch them at compile time for the sake of speed. > So with the goal of jumping to different areas in the function using an > index to an array of code positions as opcodes I have two choices. The > first is using a switch statement, which I do not like since compilers > generally insert code to insure the variable is within bounds [ If I use an > unsigned value for the switch will VC++ only check to make sure the opcode > is <= the upper bound? ]. The second is the direct style which basically > means that instead of having a break at the end of an opcode's code there is > code that will move it directly to the next opcode in line. Here's a simple > switch case example that I did get to work successfully in VC++. > void switch_type() > { > static int prog[] = {0,0,0,0,0,0,0,0,0,1}; > int *ip=prog; > int count = 10000000; > unsigned int nop = 0; > for (;;) > { > switch (*ip++) > { > case 0: > nop++; > break; > case 1: > if (--count) > { > ip=prog; > break; > }else > return; > } > } > } > Remember that direct or tail style is different from switch style byte > code in that instead of returning to the beginning of the switch statement, > each opcode's native code goes straight to the next opcode in line instead > of going back to another position and then re-entering. In other words, > there's no nesting. > What I want to achieve is a direct calling example I can use in my > benchmark that will work in VC++ and GCC that has no bound checking. While > I have no doubt that VC++ is an exceptionally smart compiler and may even > generate assembly that does do direct calling when all the optimizations for > speed are on (after all you're really just indexing an array for a switch > anyway, where you index it from isn't all that important) my worry is two > fold. First off, gcc may not be this smart and I'd like my code to be as > static as possible. And secondly, there's still a very high if not 100% > chance VC++ is still going to implement bound checking which is completely > unnecessary as the opcode generation will be handled by an assembler which > itself is used by a compiler in the finished product. > As I said, I am not opposed to swapping a few macro definitions so long > as the general structure is the same for both ports of the code. So my > question to anyone who can answer is how do I get the offset of a position > of code; the value of a label, and how do I then use that value, stored in > memory, to jump to the portion of the code I want? > As for the using Comeau the idea is starting to look very attractive for > other reasons as well. I had planned to use non-fixed length arrays as > masks for each code segment. The idea was to have a structure with some > header, multi-threaded, etc. basic information in the front and an empty > array at the bottom. I would then malloc whatever size code I need and use > one of these structures as the type of a pointer to that malloced area. > This would mean that the function wouldn't require an even deeper level > pointer to the code and would save sizeof(pointer) space in the function as > a bonus. While that does compile in VC++, it only compiles while Microsoft > extensions are enabled (I'm writing my test code in VC++ 6.0, I'm waiting > for my recently purchased MSDN Developer CustomerID to kick in). > My concerns however are that one of the biggest reasons I choose to > develop this project in Windows first instead of a Unix flavor or on a Mac > (although Unix/Linux/Solaris x86 is my main target) is that IDE for VC.NET > is just so extraordinary [ plus you just _HAVE_ to love the documentation > and help ]. It also doesn't hurt that VC++ is such a smart optimizer, but > that's just why I decided to actually compile the Windows final version in > VC++, not why I'm developing in it. I looked at the Comeau site and I must > admit I didn't quite fully grasp the concept of what it is. From my > understanding it's basically the top layer of a compiler, it compiles into > the middle code of another compiler, and then lets that compiler compile > native code from it's own middle language. What concerns me is of course > that I noticed Comeau is text prompt based system, and I heard no mention of > it being an IDE. To me this is extraordinarily important and why I choose > VC.NET in the first place. > So my question to you is how could I leverage the IDE of VC.NET, the > compiler of Comeau, and the middle language to native code abilities of > VC.NET and GCC without making this project more difficult than it already > is? > --Jonathan Ross > // To send me e-mail remove all capital letters and numbers from my e-mail > address.
> > >>> #define NEXT goto **ip++ > > >>> main() > > >>> { > > >>> static void *prog[] = > {&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&next,&&loop}; > > >>> void **ip=prog; > > >>> int count = 10000000; > > >>> next: > > >>> NEXT; > > >>> loop: > > >>> if (count>0) { > > >>> count--; > > >>> ip=prog; > > >>> NEXT; > > >>> } > > >>> } > > >>I don't know what language this is -- but it is not C or C++ as I know > it. > > >>There is no way in C or C++ to take the address of a label: the only way > I > > >>could think of doing this would be using assembler -- but that would not > be > > >>very protable. > > >Right, this is a gcc'ism. With the 4.3 release of Comeau we'll support > > >this as an extension, along with 'goto *p;', but I agree one should > > >not expect this for portable code. So to adapt it for Standard C++ > > >you'll need to perhaps use pointers to function, or a switch statement > > >or something. > > BTW, if I'm not mistaken, your code seems equivalent to this: > > int main() > > { > > int count = 10000000; > > do { > > for (int next = 0; next < 9; next++) > > ; > > } while (count-- > 0); > > return 0; > > } > > or for that matter just use 90000000L with one loop. > > -- > > Greg Comeau GA BETA:4+ New Windows Backends PLUS 'export' beta online! > > Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout > > World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90. > > Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
|
Tue, 03 Aug 2004 04:42:47 GMT |
|
 |
Greg Come #9 / 15
|
 Byte Code; Direct Style
Quote:
>> >Right, this is a gcc'ism. With the 4.3 release of Comeau we'll support >> >this as an extension, along with 'goto *p;', but I agree one should >> >not expect this for portable code. So to adapt it for Standard C++ >> >you'll need to perhaps use pointers to function, or a switch statement >> >or something. >> BTW, if I'm not mistaken, your code seems equivalent to this: >> int main() >> { >> int count = 10000000; >> do { >> for (int next = 0; next < 9; next++) >> ; >> } while (count-- > 0); >> return 0; >> } >> or for that matter just use 90000000L with one loop. > When optimized down, yes, you're absolutely correct. However, I was >simply trying to do some benchmarks to decide what form of byte code >interpreter run structure would work best on different platforms. I may not >have made it clear but I'm trying to design a Direct Calling interpreter, >which may also be called a tail call interpreter (I'm not positive).
Ok, it wasn't clear if you were just trying to create a clever delay, or some form of compute goto, or some sort of state machine (w/o giving those details). Quote: > Also, I tried to use the inline assembly of VC++ to load a label into a >register, it did not work. At this point I'm concerned about my code being >compliable in both gcc and VC++, but I would be willing to define a few >assembly macros and switch them at compile time for the sake of speed.
I'm not well versed in doing that, but I can't imagine why it's not possible as a non-portable solution (just as the gcc version is). Quote: > So with the goal of jumping to different areas in the function using an >index to an array of code positions as opcodes I have two choices.
Ok. Quote: >The >first is using a switch statement, which I do not like since compilers >generally insert code to insure the variable is within bounds
No so many compilers do this, and those that do allow you to turn it off. Quote: > [ If I use an >unsigned value for the switch will VC++ only check to make sure the opcode >is <= the upper bound? ].
Isn't that what default: is for? Quote: >The second is the direct style which basically >means that instead of having a break at the end of an opcode's code there is >code that will move it directly to the next opcode in line.
Right. Quote: >Here's a simple >switch case example that I did get to work successfully in VC++. >void switch_type() >{ > static int prog[] = {0,0,0,0,0,0,0,0,0,1}; > int *ip=prog; > int count = 10000000; > unsigned int nop = 0; > for (;;) > { > switch (*ip++) > { > case 0: > nop++; > break; > case 1: > if (--count) > { > ip=prog; > break; > }else > return; > } > } >} > Remember that direct or tail style is different from switch style byte >code in that instead of returning to the beginning of the switch statement, >each opcode's native code goes straight to the next opcode in line instead >of going back to another position and then re-entering. In other words, >there's no nesting.
I'm still not complete clear what you want to do, but it sounds like you want to make an enum with each "state" and then just use the enumerators as the values for the case ?:'s above. So instead of 0 and 1 you might have enum states { next, loop }; and then case next: and case loop: And off the top of my head, that should be reasonable efficient, probably not worse than the gcc extension and perhaps seven better. Quote: > What I want to achieve is a direct calling example I can use in my >benchmark that will work in VC++ and GCC that has no bound checking. While >I have no doubt that VC++ is an exceptionally smart compiler and may even >generate assembly that does do direct calling when all the optimizations for >speed are on (after all you're really just indexing an array for a switch >anyway, where you index it from isn't all that important) my worry is two >fold. First off, gcc may not be this smart and I'd like my code to be as >static as possible. And secondly, there's still a very high if not 100% >chance VC++ is still going to implement bound checking which is completely >unnecessary as the opcode generation will be handled by an assembler which >itself is used by a compiler in the finished product.
Most compiler use many strategies for efficient switch tables, especially if they are consecutive you should have it reasonable with both compilers. Quote: > As I said, I am not opposed to swapping a few macro definitions so long >as the general structure is the same for both ports of the code. So my >question to anyone who can answer is how do I get the offset of a position >of code; the value of a label, and how do I then use that value, stored in >memory, to jump to the portion of the code I want?
I don't know but as per above, if I understand what you're asking to do, it should be within reach. Quote: > As for the using Comeau the idea is starting to look very attractive for >other reasons as well. I had planned to use non-fixed length arrays as >masks for each code segment. The idea was to have a structure with some >header, multi-threaded, etc. basic information in the front and an empty >array at the bottom.
Do you mean like C99's ''flexible arrays''? Quote: >I would then malloc whatever size code I need and use >one of these structures as the type of a pointer to that malloced area. >This would mean that the function wouldn't require an even deeper level >pointer to the code and would save sizeof(pointer) space in the function as >a bonus. While that does compile in VC++, it only compiles while Microsoft >extensions are enabled (I'm writing my test code in VC++ 6.0, I'm waiting >for my recently purchased MSDN Developer CustomerID to kick in).
Right, MS has their own variation of this. Quote: > My concerns however are that one of the biggest reasons I choose to >develop this project in Windows first instead of a Unix flavor or on a Mac >(although Unix/Linux/Solaris x86 is my main target) is that IDE for VC.NET >is just so extraordinary [ plus you just _HAVE_ to love the documentation >and help ]. It also doesn't hurt that VC++ is such a smart optimizer, but >that's just why I decided to actually compile the Windows final version in >VC++, not why I'm developing in it.
Ok. Quote: >I looked at the Comeau site and I must >admit I didn't quite fully grasp the concept of what it is. From my >understanding it's basically the top layer of a compiler, it compiles into >the middle code of another compiler, and then lets that compiler compile >native code from it's own middle language.
That's right, and it happens transparently (for the compilers we support, for those we don't a custom port would need to be done by us for you). Currently, it used VC++ for Windows. Quote: >What concerns me is of course >that I noticed Comeau is text prompt based system, and I heard no mention of >it being an IDE. To me this is extraordinarily important and why I choose >VC.NET in the first place.
Right, Comeau doesn't come with an IDE, and currently does not integrate into Visual Studio or .NET, but we're working on that. Quote: > So my question to you is how could I leverage the IDE of VC.NET, the >compiler of Comeau, and the middle language to native code abilities of >VC.NET and GCC without making this project more difficult than it already >is?
You can't leverage Comeau C++ off of the IDE yet, though it can be used from the command line as a 3rd party tool of sorts to VC++. -- Greg Comeau GA BETA:4+ New Windows Backends PLUS 'export' beta online! Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90. Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
|
Tue, 03 Aug 2004 05:23:21 GMT |
|
 |
Mike #10 / 15
|
 Byte Code; Direct Style
Quote:
>Jonathan: I not sure if I fully understand your concern about the Visual C++ >compiler bounds-checking a switch statement. I do not believe that any C++ >compiler will bounds check the expression in a switch-statement. If there is >not a case label that corresponds to the value of the expression then the >compiler will choose the default label, or if there is not a default label, >it will just skip the body of the switch-statement.
Maybe the worry was the set of instructions: cmp eax, 12 // 12 is just an example jg end_of_switch jmp jmp_table[eax*4] ? It would slow down the code a bit (especially on the not too good IA-32) compared to not generating those instructions and just doing jmp jmp_table[eax*4] However, since we are talking about pretty deep stuff here, would the VC specific __assume help the optimizer? Would something likt the following perhaps help? extern unsigned int iVal; __assume(iVal < 2); switch (iVal) { case 0: do_zero_stuff(); break; case 1: do_one_stuff(); break; Quote: }
Would the check still be made (if iVal < 2), or would that __assume hint to the optimizer tell it that "these are the only two legal values in this code and if you gimme something else it's your fault", and not insert the extra "bounds"? /Mike
|
Tue, 03 Aug 2004 05:22:35 GMT |
|
 |
Jason Shirk [MSFT #11 / 15
|
 Byte Code; Direct Style
Quote: > However, since we are talking about pretty deep stuff here, would the > VC specific __assume help the optimizer? Would something likt the > following perhaps help? > extern unsigned int iVal; > __assume(iVal < 2); > switch (iVal) { > case 0: do_zero_stuff(); break; > case 1: do_one_stuff(); break; > } > Would the check still be made (if iVal < 2), or would that __assume > hint to the optimizer tell it that "these are the only two legal > values in this code and if you gimme something else it's your fault", > and not insert the extra "bounds"? > /Mike
It's even simpler. Try: switch (iVal) { case 0: do_zero_stuff(); break; case 1: do_one_stuff(); break; default: __assume(0); Quote: };
In our code, we have a macro UNREACHED which is an assertion in test builds, and __assume(0) in retail builds. Jason Shirk VC++ Compiler Team
|
Tue, 03 Aug 2004 05:31:55 GMT |
|
 |
Jonathan Ros #12 / 15
|
 Byte Code; Direct Style
Thanks Mike, that's what I was trying to say. I was in the middle of trying to figgure out how to keep gcc from optimizing a switch so I could give a demo, thank god you answered since gcc's assembly is pretty ugly, doesn't fit the intel standards. Also, thanks to Mike and Jason for clueing me into assume, that's fantastic. That leaves one final bit, if I nest my switch statment in an infinite loop is VC++ smart enough to choose to tail call (as explained earlier); go to the next case in the switch without going back to the begining and reusing that code. In otherwords, an inline switch at the end of every case. I realize that due to caching it may actually be optimial in some cases to go to the begining and reuse the jump into the vector table [ as in Mike's example: jmp jmp_table[eax*4] ]. So what I'm asking is, if having that jump in the end of every case's code is more efficent in the specific case, does VC++ put it there? I'm really sorry I'm being such a nit-picker, but speed really does matter in this case. Also if I were lazy enough to just take the first thing that worked I'd probarbly still be writing code in VB like my highschool taught me all so well [ teacher wouldn't let us use gotos, but also wouldn't let use classes or modules since it would just complicate our programs ]. --Jonathan Ross, thanks
|
Tue, 03 Aug 2004 01:19:23 GMT |
|
 |
Jonathan Ros #13 / 15
|
 Byte Code; Direct Style
Quote: > Right, Comeau doesn't come with an IDE, and currently does not > integrate into Visual Studio or .NET, but we're working on that.
Wow wow wooooooow. Are you saying that Comeau will eventually let me write C++ code in the VC.NET interface, write and debug Comeau code (maybe even profile), etc., etc., compile into MSML, then get VS.NET to optimize the heck out of it and after I'm done testing I can take the source, compile it in a different platform's Comeau? VS IDE (debugging, editing) + Comeau Code -> MSML -> Optimized the heck out of Win32/64 code Comeau Code developed above -> Other ML -> Other Native Code To think, I was actually starting to doubt my MSDN Developer Subscription. Granted, I may not have gotten that little flow perfectly but if it's anything like that... Sign me up for beta testing and let me buy the first copy you sell :) --Jonathan Ross, very very e{*filter*}d PS: Got a link to it describing it any further? I think this is getting a bit off thread here, just post the link so everyone can read it and we don't clutter the boards anymore. And I'm serious about beta testing, I tend to break the unbreakable; as you can probably see why from this thread.
|
Tue, 03 Aug 2004 01:31:44 GMT |
|
 |
Mike #14 / 15
|
 Byte Code; Direct Style
Quote:
> Thanks Mike, that's what I was trying to say. I was in the middle of >trying to figgure out how to keep gcc from optimizing a switch so I could >give a demo, thank god you answered since gcc's assembly is pretty ugly,
It's not GCC, it's the horrible AT&T version that GNU uses! :-) Quote: >doesn't fit the intel standards. Also, thanks to Mike and Jason for clueing >me into assume, that's fantastic.
I agree that you can get some pretty amazing results from __assume, but also realize it's not perfect. To display how some switch code without __assume is generated, try to compile duffs device (just do a google search, you'll find it at e.g. lysator.liu.se). It's actually quite interesting to see how some compilers generate code, even when told to optimize for size (O1). (I hope e.g. Jason will try this now, right? :->) Quote: >That leaves one final bit, if I nest my switch statment in an infinite >loop is VC++ smart enough to choose to tail call (as explained earlier); go >to the next case in the switch without going back to the begining and >reusing that code.
I don't know about VC7, but IIRC the VC6 optimizer did no such thing. I'm not completely sure what you're trying to do, but if you can use C++ I can tell you that inlined function templates can sometimes be a helluvalot more efficient than any "ordinary" code. I have f.e.. written a user-mode AlphaBlend that's on average ~10% faster than MS' W2k version that runs in kernel-mode (!) using some carefully selected template inlines (and I'm not cheating and using MMX or some such). Quote: > In otherwords, an inline switch at the end of every >case. I realize that due to caching it may actually be optimial in some >cases to go to the begining and reuse the jump into the vector table [ as in >Mike's example: jmp jmp_table[eax*4] ]. So what I'm asking is, if having >that jump in the end of every case's code is more efficent in the specific >case, does VC++ put it there?
Actually, that question is more-or-less impossible to answer without knowing 1) what CPU you're targetting, 2) how the "pipes" are filled at that point. Since you have MSVC I assume you have access to the crt src. Have a look at e.g. memcpy.asm and look at the comments about U and V. That are the two pipes in a Pentium processor. Running that code on e.g a 486 would probably be slower than a simple repne (I'm just guessing here), and I'd also assume that a PIII optimized version would look nothing like it. Just to display that the number of variables are quite large. :-) Quote: >I'm really sorry I'm being such a nit-picker, but speed really does >matter in this case.
Then I'd suggest you drop by IAL (Intel Architecture Labs) and see what they might have. Pipe bubbles are killers as you probably know, and imagine something like the P4 getting a bubble in it's 20-stage (or was it 16) pipe. :-< Quote: >Also if I were lazy enough to just take the first >thing that worked I'd probarbly still be writing code in VB like my >highschool taught me all so well [ teacher wouldn't let us use gotos, but >also wouldn't let use classes or modules since it would just complicate our >programs ].
Thank god there are still people that care about small size and high performance! What if everyone just cared about dotnot? :-) /Mike
|
Tue, 03 Aug 2004 08:54:24 GMT |
|
 |
Greg Come #15 / 15
|
 Byte Code; Direct Style
Quote:
>> Right, Comeau doesn't come with an IDE, and currently does not >> integrate into Visual Studio or .NET, but we're working on that. >Wow wow wooooooow. Are you saying that Comeau will eventually let me write >C++ code in the VC.NET interface, write and debug Comeau code (maybe even >profile), etc., etc., compile into MSML, then get VS.NET to optimize the >heck out of it and after I'm done testing I can take the source, compile it >in a different platform's Comeau?
That's the intent, whether it can actually occur is another situation. Quote: >VS IDE (debugging, editing) + Comeau Code -> MSML -> Optimized the heck >out of Win32/64 code > Comeau Code developed above -> Other ML -> Other Native >Code > To think, I was actually starting to doubt my MSDN Developer >Subscription. Granted, I may not have gotten that little flow perfectly but >if it's anything like that... Sign me up for beta testing and let me buy >the first copy you sell :) >--Jonathan Ross, very very e{*filter*}d >PS: Got a link to it describing it any further? I think this is getting a >bit off thread here, just post the link so everyone can read it and we don't >clutter the boards anymore. And I'm serious about beta testing, I tend to >break the unbreakable; as you can probably see why from this thread.
There's no link to this yet. It still needs work first. And now that .NET is a reality, we need to revisit it. Hopefully something will appear sooner than later... -- Greg Comeau GA BETA:4+ New Windows Backends PLUS 'export' beta online! Comeau C/C++ ONLINE ==> http://www.*-*-*.com/ World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90. Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
|
Wed, 04 Aug 2004 00:27:17 GMT |
|
|
|