Parallel usage rules

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Parallel usage rules

Post by Folknology »

I need to share parts of an array for both read and write across threads, although the same index is never used concurrently across threads and is thus safe, unfortunately the XC compiler won't let me do this:

Code: Select all

.. violates parallel usage rules
Is there any way to suppress this or selectively (by variable/array) override it?

regards
Al


User avatar
Paolomio
Experienced Member
Posts: 64
Joined: Tue Oct 05, 2010 7:33 pm

Post by Paolomio »

You could pop up into C, pass pointers around (via channels, if necessary), and go to town. Passing resources via channels is a great technique to get around the draconian usage rules...but you need to be sure you know what you're doing.
User avatar
Interactive_Matter
XCore Addict
Posts: 216
Joined: Wed Feb 10, 2010 10:26 am

Post by Interactive_Matter »

Does this help you:

#pragma unsafe arrays (XC only)

This pragma disables the generation of run-time safety checks that prevent indexing an invalid array element within the scope of the next do, while or for statement in the current function; outside of a function the pragma applies to the next function definition.

(from the tools user guide)

Marcus
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Thanks Interactive_Matter the unsafe arrays I think deals with out of bounds checking rather than Parallel usage rules, I tried it just in case but no result.

Paolomio - Yeah passing pointers over channels is something I have seen before (its used in the ethernet module I think) its ugly but may have to resort to it. In the long term the solution will be C based anyhow, but I was trying to do something quick and dirty to test a theory in XC until I hit the road block, looks like I will have to do the whole project in C now, teach me to take short cuts..

regards
Al
User avatar
Paolomio
Experienced Member
Posts: 64
Joined: Tue Oct 05, 2010 7:33 pm

Post by Paolomio »

Yes, #pragma unsafe arrays only disables bounds checking--necessary to speed things up in time-critical bits of code, but does nothing regarding parallel usage rules. There is no nifty flag to turn off the helicopter-mom features of XC I'm afraid, although I've requested that they add a TRAINING_WHEELS=off compiler flag.

While ugly, using channels to pass around resources is the only scheme I've found that really works. If anyone else has any other techniques they would be good to know. I've used this to pass channels, pointers, even ports, with success.

Paul
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Something as simple as a pragma to mark a variable/array/structure as sharedwould be nice.

Code: Select all

#pragma I really do no what I'm doing with this shared storage element
or a shorter version perhaps:

Code: Select all

#pragma shared array
regards
Al
MaxFlashrom
Experienced Member
Posts: 82
Joined: Fri Nov 05, 2010 2:59 pm

Post by MaxFlashrom »

Hi Al,
You can subvert the checking rules with inline assembler.
I've used the code shown below. You can make it fancier, putting bounds checking back in so it looks more like the compiler with what the compiler generates with an lsu and ecallf, if you also pass a bounds parameter.
Reading the compiler output is often instructive.

Also it could be wrapped in an inline function rather than #defines, perhaps giving a more natural read function returning a value, so one could write

Code: Select all

val=readarray(idx);

Code: Select all

#define writeArray(arr, idx, val) asm("stw %0, %1[%2]":: "r"(val), "r"(arr), "r"(idx))
#define readArray(arr, idx, val) asm("ldw %0, %1[%2]": "=r"(val): "r"(arr), "r"(idx))
Note that this was written to work only with array elements that are word-sized. For byte arrays you'd need to use ld8u and st8; ld16s, st16 for 16bit quantities. ld16s sign extends, so you'd have to zext the top bits for negative/large numbers if you don't want sign extension to 32 bits.

Generally, the XC rules are useful protection;when you throw them out you expose yourself to the possibility of loads of trouble, but I'm sure you know that ;-)

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

Post by lilltroll »

Yes indeed, or we can cast a pointer to the first array index with help of

Code: Select all

add r2,r1,0

and send the pointer to different threads
but something like

Code: Select all

#pragma shared array
would make the code more clean and easy to understand, and the compiler would also handle the size of the elements.

We already use unsafe arrays to save time/instructions, and that is the main reason to use shared array as well. In some cases it is to slow to solve the problem with channels, like using line buffers etc when the receiver reads data in a different order than the transmitter.
Probably not the most confused programmer anymore on the XCORE forum.
wardy
Active Member
Posts: 37
Joined: Tue Jul 06, 2010 2:26 pm

Post by wardy »

Just out of interest - what is the rational behind preventing the sharing of arrays? I ask because there is the obvious work around by using C, however, as a pragma hasn't been implemented, it makes one wonder whether there are problems which can be encountered which could be encountered with the work around?
Heater
Respected Member
Posts: 296
Joined: Thu Dec 10, 2009 10:33 pm

Post by Heater »

wardy,
what is the rational behind preventing the sharing of arrays
Simple answers might be:

1) If you are writing code with many threads and if you have many cores on which to run those threads then having those threads only work in their own private memory space and only communicate via channels it becomes easy to run any thread on any core as speed and/or space requirements dictate. Clearly threads that are using shared memory cannot be running on separate cores and your code unable to take advantage of multiple cores/chips.

2) Multithreaded programming with shared memory generally requires mechanisms to ensure that threads do not access common data structures at the same time and thus corrupting the data. Enter the world of mutexes, semaphores, locks or whatever. This is introduces complexity into your code and is prone to bugs. Your code is much easier to reason about if threads do not share memory.

A less simple answer is that XMOS and the xcores are obviously in a lineage from INMOS and the Transputer. The whole philosophy is built around the idea of many processors working together via communications channels. Thus enabling the simplification of software and the ability to scale up to large numbers of parallel executing processes.

This is all springing from the work of C. A. R. Hoare who first described Communicating Sequential Processes (CSP) in a 1978 paper. CSP is a formalization of my hand waving arguments above. http://en.wikipedia.org/wiki/Communicat ... _processes

Of course it is the nature of users of devices to want to push performance to the limit or do other weird stuff and so here we are asking for shared arrays/memory and all the dangers that come with it:)