Global Variables

Non-technical related questions should go here.
User avatar
rubenc
Active Member
Posts: 40
Joined: Fri Jul 22, 2011 2:31 pm
Contact:

Post by rubenc »

Not yet, but I will. I need to read the wiki info you send me
Thankyou tough!


User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

You can cast arrays, struct etc to a "pointer" in XC with inline asm.

An example from my code.
I use a struct

Code: Select all

struct injectiontime_t {
	int Periodtime[4];
	int Hiperiodtime[4];
	int RiseTime[4];
	int FallTime[4];
};
The struct is used in one thread.

In an other thread on the same core I want to read data from that struct, without affecting the critical timing of that thread.

Code: Select all

asm("ldw %0,%1[0]": "=r"(period): "r"(injection.Periodtime));
printf("Period Freq is %d Hz, Duty cycle is %d\n", 100000000/period);
printf is a very stupid example since that stalls the chip reading via JTAG.
But assume you did something else, like sending it via Ethernet, or UART or ....

Code: Select all

asm("ldw %0,%1[1]": "=r"(period): "r"(injection.Periodtime));
Would read the next word in the array, and will be translated to an immediate instruction.

Code: Select all

asm("ldw %0,%1[%2]": "=r"(period): "r"(injection.Periodtime),"r"(i));
Would read the word at position i in the array.
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
JohnWilson
Active Member
Posts: 38
Joined: Fri Oct 28, 2011 10:53 pm
Contact:

Post by JohnWilson »

Why does XC have these restrictions in the first place? Is it because of some actual hardware problem (there's no cache or out-of-order execution to cause the usual kinds of mP insanity, so all I can think of is trouble with collisions when different hyperthreads try to read *and* write the same location during the same memory cycle), or is it just that they think we don't know how to use shared memory safely? Maybe I'm misunderstanding what's going on.
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

JohnWilson,
Why does XC have these restrictions in the first place?
It's all due to the fact that that threading and parallel processing support in XC is based on the one of the mathematical theories of concurrency called Communicating Sequential Processes (CSP) as developed by C.A.R. Hoare. CSP is a useful tool for specifying and verifying the behaviour of concurrent systems.

http://en.wikipedia.org/wiki/Communicating_sequential_processes


CSP was a fundamental idea of the Transputer chip and Occam language from Inmos and now XC and the XMOS devices.

One of the main rules of CSP is that processes do not share memory but instead communicate via well defined channels. This makes design and reasoning about such systems possible. Rather like removing GOTO from structured languages.

On a simple an practical level. Say you are running many concurrent tasks on a single CPU and they share memory. And then you want to split that group of tasks over multiple processors to gain performance or add additional tasks. That relocation of work is much easier if your original threads communicate via channels. You only have to migrate threads to other cores and make use of the hardware channels instead. Rather like you don't worry about where your program is in memory you should not have to worry about where it is in "processor space".

Of course down in the trenches the first thing people ask for is shared memory between threads. Often because that is what they are used to having or sometimes because you really need it for performance reasons.

In that case you have the options suggested here.
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

JohnWilson,

From silicon point of view I guess it's much easier to put multiple cores on a chip communicating with channels than it is to have them share memory, implementing caches, keeping everything coherent etc etc.

Not to mention using share memory between cores like that destroys the timing determinism of your code as many cores fight for access to the same data.

And of course sharing memory means sharing bandwidth to memory so your performance does not scale up linearly with number of cores.

So, given no share memory between cores, there can be no share global variables between threads running on different cores. Makes sense to also remove global access from threads in the same core. It's elegant and predictable. The principle of "least surprise".

Actually I'm surprised XC allows threads to even allow a single writer and multiple readers of global variables.
User avatar
JohnWilson
Active Member
Posts: 38
Joined: Fri Oct 28, 2011 10:53 pm
Contact:

Post by JohnWilson »

Heater wrote: Actually I'm surprised XC allows threads to even allow a single writer and multiple readers of global variables.
Well that's really what I'm getting at -- if I'm reading the docs correctly (Thread Disjointness Rules in section 3.2 of "Programming XC on XMOS Devices"), XC *doesn't* allow this, officially anyway. The only way variables may be shared between two threads is if they both have only read access. I've spent many years writing code where one thread (or ISR) can feel free to leave stuff in memory for another thread (or mainline) to find, possibly after being poked (software interrupt, byte sent over a pipe, etc.) and possibly needing MFENCE etc. to make sure other hyperthreads see things happen in the right order. So yes I don't mind using a channel to knock the receiving thread out of a "select" or whatever so it will notice the change, but it seems crazy to have to wad everything up and stuff it through a channel when it was already sitting in memory that both threads can access. UNLESS there's some hardware limitation, like that a write to a location during the same cycle that another thread reads it will actually be *lost*. Delayed is one thing, but lost is no good!
User avatar
Bianco
XCore Expert
Posts: 754
Joined: Thu Dec 10, 2009 6:56 pm
Contact:

Post by Bianco »

There are no hardware limitations.
You can do shared memory in C or assembly.

The advantage of using channels is that your software modules (threads) may become location independent. Say you have two modules running on the same core. They can communicate using shared memory. But what if you want to relocate one of the modules to another core? Each core has it's own memory space so shared memory cannot be done. If your design is based on channel communication you do not have to change a single line of code to run that module on another core.
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am
Contact:

Post by segher »

JohnWilson wrote:Well that's really what I'm getting at -- if I'm reading the docs correctly (Thread Disjointness Rules in section 3.2 of "Programming XC on XMOS Devices"), XC *doesn't* allow this, officially anyway.
That is correct.
The only way variables may be shared between two threads is if they both have only read access.
Right. You can write to those vars _before_ you run those parallel threads though.
I've spent many years writing code where one thread (or ISR) can feel free to leave stuff in memory for another thread (or mainline) to find, possibly after being poked (software interrupt, byte sent over a pipe, etc.) and possibly needing MFENCE etc. to make sure other hyperthreads see things happen in the right order. So yes I don't mind using a channel to knock the receiving thread out of a "select" or whatever so it will notice the change, but it seems crazy to have to wad everything up and stuff it through a channel when it was already sitting in memory that both threads can access.
In the common case, stuff isn't already sitting in memory, but you have to write it
there first, which is quite a bit *more work* than writing it immediately to a channel!

There are a few cases where you need to buffer stuff up though (elasticity buffers,
or when you need to keep data around for a resend if you have an unreliable
transport somewhere in your pipe, for example). Most of the time it is quite
easy to isolate those memory accesses through some C code (or asm, if speed
really matters -- but then you write the whole thread routine in asm anyway).
UNLESS there's some hardware limitation, like that a write to a location during the same cycle that another thread reads it will actually be *lost*. Delayed is one thing, but lost is no good!
I have not seen lost writes or any other corruption. I believe the sram is a write-through
affair, in the sense that a reader will get the new data when it is written at that same time,
but I'm not sure.
User avatar
JohnWilson
Active Member
Posts: 38
Joined: Fri Oct 28, 2011 10:53 pm
Contact:

Post by JohnWilson »

OK fair enough! If it's entirely dogma to prepare me for a future that will almost definitely never come (moving a 2- or 3-thread project onto a multi-core XS1) and there's no technical reason why cheating at XC's rules with assembly code won't work, I'm happy. Thanks!!!
Post Reply