ImageCraft C: pure COG code and multiprocessor access
I don't think this will make it to the First Release, but since there will be demand for fast drivers and other COG only code (a forum member mentions VGA driver etc.), I did some thinking on the subject:
Recap: by default, the C program compiles to a (Large Memory Model LMM) virtual machine executing instructions from the HUB memory at about 25% speed of native code. So the main COG (usually COG0) will not have any memory to run non-LMM code except the kernel stuff. Any non-LMM code then has to be run on other COGs.
SMM COG functions are really standalone programs and limited C library will be provided. Details TBD. May be the compiler will only implement the bare minimum (meaning 32 bits mul/div) to support C and anything else will have to be provided by the users. There will need to be a different runtime architecture for SMM.
So a possibility is to add a pragma for native COG functions, one appeared, all the functions and data following are compiled into a single "unit." global/static variables are COG RAM, and extern variables are HUB RAM. I am not even sure if we should bother to provide a stack or local registers and the like. May be every variables regardless whether it is global/static/local just gets a different COG RAM address and assume people who want COG functions are advanced programmers who are aware of these sort of issues.
#pragma smm(name1)
static int myint; // COG RAM
int myint2; // also COG RAM
extern int otherint; // HUB RAM, must be defined by other
void foo(int int_param) { // first function gets compiled to location 0 ... }
void bar() { ...}
#pragma smm(name2) // a different set of COG functions
...
#pragma lmm // switch back to LMM mode
void lmm_func() { ... }
The linker would of course emits errors if a set of COG functions exceed 512 longs. You can have as many cog names as you like, but typically 7 or less. The assembler generated will look something like
.area name1(cog)
_foo::
...
So if you want to write cog code in asm, you just need to follow the conventions. (I am assuming I can get the asm guy to implement this
)
At the C level, you would use a library function:
extern void foo(int);
COGINIT_SMM(foo, int_param, cog_id);
...
A (normal) LMM function can be started on a COG like this:
COGINIT_LMM(lmm_func, int_param, cog_id);
Of course all LMM functions are sharing code in the HUB RAM so all C and other library functions are available. The users are responsible for COGs and other resource sharing issues. There will be equivalence of COGSTOP etc. too of course.
That should cover it. This gives access to the native Propeller multiprocessing. At some points, it would be nice to add multi-threading OS on top of the native capabilities. I know Bill Henning and others have some ideas. One step at a time though. As I said, this probably will *NOT* make it to the First Release as it is.
// richard
Recap: by default, the C program compiles to a (Large Memory Model LMM) virtual machine executing instructions from the HUB memory at about 25% speed of native code. So the main COG (usually COG0) will not have any memory to run non-LMM code except the kernel stuff. Any non-LMM code then has to be run on other COGs.
SMM COG functions are really standalone programs and limited C library will be provided. Details TBD. May be the compiler will only implement the bare minimum (meaning 32 bits mul/div) to support C and anything else will have to be provided by the users. There will need to be a different runtime architecture for SMM.
So a possibility is to add a pragma for native COG functions, one appeared, all the functions and data following are compiled into a single "unit." global/static variables are COG RAM, and extern variables are HUB RAM. I am not even sure if we should bother to provide a stack or local registers and the like. May be every variables regardless whether it is global/static/local just gets a different COG RAM address and assume people who want COG functions are advanced programmers who are aware of these sort of issues.
#pragma smm(name1)
static int myint; // COG RAM
int myint2; // also COG RAM
extern int otherint; // HUB RAM, must be defined by other
void foo(int int_param) { // first function gets compiled to location 0 ... }
void bar() { ...}
#pragma smm(name2) // a different set of COG functions
...
#pragma lmm // switch back to LMM mode
void lmm_func() { ... }
The linker would of course emits errors if a set of COG functions exceed 512 longs. You can have as many cog names as you like, but typically 7 or less. The assembler generated will look something like
.area name1(cog)
_foo::
...
So if you want to write cog code in asm, you just need to follow the conventions. (I am assuming I can get the asm guy to implement this
![smile.gif](http://forums.parallax.com/images/smilies/smile.gif)
At the C level, you would use a library function:
extern void foo(int);
COGINIT_SMM(foo, int_param, cog_id);
...
A (normal) LMM function can be started on a COG like this:
COGINIT_LMM(lmm_func, int_param, cog_id);
Of course all LMM functions are sharing code in the HUB RAM so all C and other library functions are available. The users are responsible for COGs and other resource sharing issues. There will be equivalence of COGSTOP etc. too of course.
That should cover it. This gives access to the native Propeller multiprocessing. At some points, it would be nice to add multi-threading OS on top of the native capabilities. I know Bill Henning and others have some ideas. One step at a time though. As I said, this probably will *NOT* make it to the First Release as it is.
// richard
Comments
The main reason for doing pure "cog code" is to perform time critical operations or very tightly optimized and time critical operations like for VGA or TV display drivers or very high speed asynchronous serial I/O, etc.· The C compiler simply does not have the capability·of accepting information from the programmer of sufficient detail (in terms of specific execution path timing) to do the "optimal" code generation.· Really the only practical way to do this is to provide those routines in assembly as a block of data to be used with the COGINIT instruction.· The kind of routines you're describing are appropriate to write in C, but don't include these "super-tight" drivers.· Something like a PS/2 keyboard or PS/2 mouse driver or a high speed serial I/O driver would be appropriate.· These are small enough that they would fit in a cog even with the modest inefficiencies of compilation and have enough "slop" in terms of speed that the additional time inefficiencies wouldn't matter.· They'd be mostly fast enough to do using the LMM kernel·in another cog, but would also work this way.
Right, if I understand what you are saying, there will be a set of drivers that need to be written in assembly. No problem, what I am proposing is really just a set of asm directives that can be used to integrate the said drivers in either asm source or object form to a C project.
Additionally, sounds like we should allow the linker to combine prebuilt .bin files. So a project may contain
C files
asm files
bin files with a symbol so the C module can access it by name for the COGINIT function
object files
and the compiler system will just compile and assemble if needed, and the linker will combine everything into a single .bin file. So if you have a driver written in current assembler format, you won't even have to port the source or anything.
Is that a question, comment, or? In all my posts, did I ever mention that we won't allow that sort of capabilities?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker
Propeller Applications Engineer
Parallax, Inc.
Post Edited (Paul Baker (Parallax)) : 12/7/2007 4:57:48 AM GMT
Yes, First Release will not have the VGA/TV driver. If you want to wait until a future release that does, feel free to do so
As for whether other people will buy our compiler without these drivers, we will just have to see. Judging from the responses though, I think the answer would be yes, we will have some customers. Time To Market is important, and again, we are later than I would like already and there is no way I will delay the compiler further for this reason alone.