hi all:
In a core, how to use the same memory location in the multiple threads in a core?
Have any one done the ways?
I hope the memory pool is used for data & control processing.
How to set the compiler to ignore these pool memory range?
Or there has the lib to manipulate these memory pool?
Thank you!
How to use the same memory in multi threads?
-
- Member
- Posts: 15
- Joined: Fri Nov 11, 2011 9:57 am
-
- XCore Addict
- Posts: 147
- Joined: Tue Feb 23, 2010 6:55 pm
From C code you can access the memory however you like, so calling some C code to do the memory access from the threads will be the easiest option.
-
- Member
- Posts: 15
- Joined: Fri Nov 11, 2011 9:57 am
Hi Hacker:
I think over the access of the same memory between threads in a core.
How to implement?
Through channel tell the threads where the shared memory location?
Or directly assign the memory address but how?
Can you give an example?
By the way if the access of the same memory between 2 threads in different cores,
is there impossible, right?
I think over the access of the same memory between threads in a core.
How to implement?
Through channel tell the threads where the shared memory location?
Or directly assign the memory address but how?
Can you give an example?
By the way if the access of the same memory between 2 threads in different cores,
is there impossible, right?
-
- Respected Member
- Posts: 296
- Joined: Thu Dec 10, 2009 10:33 pm
porche,
Two threads in XC cannot share the same memory.
Each of those threads could call a C function to access a shared memory region.
The address of the shared pool being only know to the C code.
So create a C module. In there define your shared memory area, an array or struct or whatever. Also define access functions in C that can be called from your XC code.
Be ready to deal with race conditions and corruption as your XC threads make simultaneous updates to that data area.
No threads on different cores cannot share RAM. Each core has it's own RAM space.
Two threads in XC cannot share the same memory.
Each of those threads could call a C function to access a shared memory region.
The address of the shared pool being only know to the C code.
So create a C module. In there define your shared memory area, an array or struct or whatever. Also define access functions in C that can be called from your XC code.
Be ready to deal with race conditions and corruption as your XC threads make simultaneous updates to that data area.
No threads on different cores cannot share RAM. Each core has it's own RAM space.
-
- Respected Member
- Posts: 363
- Joined: Thu Dec 10, 2009 10:17 pm
The easiest is to move your code in to a .c file and then you can do with memory whatever you like just as in C, the downside of using C is that all the hardware is not available to you(Pins,timers etc) but it would be possible to make wrappers for those in XC if timing is not critical.
-
- XCore Expert
- Posts: 844
- Joined: Sun Jul 11, 2010 1:31 am
You can access the hardware resources directly from C just fine;Berni wrote:The easiest is to move your code in to a .c file and then you can do with memory whatever you like just as in C, the downside of using C is that all the hardware is not available to you(Pins,timers etc) but it would be possible to make wrappers for those in XC if timing is not critical.
since C does not have language constructs for that, you use compiler
builtins or inline assembler statements.
What XC brings to the table is a set of simple rules that make it
possible to reason about how the program works when running
on multiple threads (or cores). Sometimes in an XC program you
want to break those rules, because they are too limiting (for example
some shared buffer thing), but then you have to enforce correctness
yourself. This is useful for components that are mostly "stand-alone",
have a small "surface"; on the other hand, wrapping tiny pieces of XC
in a C interface gives you none of the good things of XC, but does
give you all its downsides (and you get some lovely call overhead
"for free" ;-P )
-
- Member
- Posts: 15
- Joined: Fri Nov 11, 2011 9:57 am
Hi Segher:
Indeed the sharing buffers is a hot point. Use channel to pass the big buffers to other threads is not as good as to pass the reference.
Think about a scenario, one thread has one large size data and other threads want to read this large size data to process.
But how to pass the reference in .xc to another .xc (or .c) in different threads? Can you give a sample code for me to research ?
Indeed the sharing buffers is a hot point. Use channel to pass the big buffers to other threads is not as good as to pass the reference.
Think about a scenario, one thread has one large size data and other threads want to read this large size data to process.
But how to pass the reference in .xc to another .xc (or .c) in different threads? Can you give a sample code for me to research ?
-
- Respected Member
- Posts: 363
- Joined: Thu Dec 10, 2009 10:17 pm
Well i dont think i remember doing shared variables, but by how much this is used there could be something to make it ignore this(There is a #pragma unsafe arrays but from what i read all that does is remove boundary checking to speed stuff up)
Well one way i could see it possible to share a variable over a channel is if you used (unsigned int)%your_var; to get an address of the variable that you can pass over a channel as a normal integer. On the other side you again feed that back to a C file where you go distant_var = (*unsigned int)addr; (distant_var has to be a pointer). But do remember that you must do this between threads on the same core since if its not all it does is read junk without any warning.
Well one way i could see it possible to share a variable over a channel is if you used (unsigned int)%your_var; to get an address of the variable that you can pass over a channel as a normal integer. On the other side you again feed that back to a C file where you go distant_var = (*unsigned int)addr; (distant_var has to be a pointer). But do remember that you must do this between threads on the same core since if its not all it does is read junk without any warning.
-
- XCore Expert
- Posts: 956
- Joined: Fri Dec 11, 2009 3:53 am
- Location: Sweden, Eskilstuna
If you need acess to channels and ports, it might be easier to create a pointer with asm in xc.
first
This example is for hispeed RS232 working with packages of data ,including crc32. In this example I have a circular buffer called data with size char[]
The receiving thread works as usual with xc. When a package has been received, the thread sends a control token plus the starting index of the package in the buffer as a uint32 on a streaming channel.
The supervising thread manipulating the data uses a select
I now have information on where to go next based on the control token (command), and I also have a pointer (prt) to the memory where I can start to read.
Depending on how I wish to interpret the data in the buffer, I can use the instructions ld8u, ld16s or ldw to access the array.
An example would be that the data holds 3 signed shorts
PS1, using short or longs instead of chars, you should not use add to calculate the offset, instead use ldaw for words etc. DS.
PS2, ld16s and ldw must be align in memory. An address to ld16s must be even, and an address to ldw must be an multiple of 4. DS.
PS3. If you for an example need to avoid that the RX thread stalls, due to that the master thread is busy, you could send only a control token over the channel. An control token is only 8 bits, and the channel buffer is 64 bits. That way I could receive 8 packages of data, without stalling the receiving thread even if the master thread is occupied with other operations. (I would need to create a new vector that holds the buffer-index's.) DS.
first
Code: Select all
static char data[256]
The receiving thread works as usual with xc. When a package has been received, the thread sends a control token plus the starting index of the package in the buffer as a uint32 on a streaming channel.
The supervising thread manipulating the data uses a select
Code: Select all
case sinct_byref(c_RX,command):
c_RX:>start;
asm("add %0,%1,%2" : "=r"(ptr) : "r"(data) , "r"(start));
Depending on how I wish to interpret the data in the buffer, I can use the instructions ld8u, ld16s or ldw to access the array.
An example would be that the data holds 3 signed shorts
Code: Select all
asm("ld16s %0,%1[%2]": "=r"(short1) : "r"(ptr) , "r"(0) ); //load word with sign extension
asm("ld16s %0,%1[%2]": "=r"(short2) : "r"(ptr) , "r"(1) );
asm("ld16s %0,%1[%2]": "=r"(short3) : "r"(ptr) , "r"(2) );
PS2, ld16s and ldw must be align in memory. An address to ld16s must be even, and an address to ldw must be an multiple of 4. DS.
PS3. If you for an example need to avoid that the RX thread stalls, due to that the master thread is busy, you could send only a control token over the channel. An control token is only 8 bits, and the channel buffer is 64 bits. That way I could receive 8 packages of data, without stalling the receiving thread even if the master thread is occupied with other operations. (I would need to create a new vector that holds the buffer-index's.) DS.
-
- XCore Expert
- Posts: 844
- Joined: Sun Jul 11, 2010 1:31 am
That is correct: if you have to delay sending the data on (maybe becauseporsche wrote:Indeed the sharing buffers is a hot point. Use channel to pass the big buffers to other threads is not as good as to pass the reference.
the receiver is busy -- try to avoid that, stream everything, go with the
flow!), or if more than two threads on the same core as your sender have
to receive the same data and you would rather spend more time in the
receivers and less in the sender (usually advantageous because of how
the thread scheduling interacts with the receive code), or if *both* the
sender and the receiver need the data in memory for other reasons (for
example, if they both need to do some transform on it that requires random
access to the data); in such cases, it is better to pass the data around
in memory.
In all other cases, it is faster to pass the data over a (streaming)
channel. This also has the rather big advantage that your code components
become more decoupled; also, you can then move some components to another
core to get a snugger fit.
But sometimes, you really want to have a shared buffer, for good reasons
(which doesn't happen so often) or bad reasons ("it's what we're used to").
You cannot do it in pure XC (you can do some tricks with inline assembler).But how to pass the reference in .xc to another .xc (or .c) in different threads? Can you give a sample code for me to research ?
If you go via C, it is easy: every (global) variable is shared between all
threads. Well, "easy": you now have to solve the data hazards and other
ordering stuff yourself.
I don't have any example code in either C or XC, sorry.