Accessing another processes memory

New to XMOS and XCore? Get started here.
Treczoks
Active Member
Posts: 38
Joined: Thu Mar 21, 2013 11:18 am
Contact:

Accessing another processes memory

Post by Treczoks »

Hi!

I have a process A performing some measurements and storing the result in memory (a simple unsigned variable). Another process B (on the same tile) very occasionally needs to know about the result. If I try to share the value, the compiler hits me with a "error: use of `ReceivedAudio' violates parallel usage rules". Now what I don't want is to keep a channel open just to get this value. Imagine A to do the measurement of PSU voltage or case temperature, and B being a process that responds to the hosts commands, one of which could be "show temperature". Blasting the host communication process with gazillions of values it'll never ever need is IMHO a waste of resource as much as the need to constantly read the values to avoid a blocking of the sender.

What can I do, and what are the implications (memory timing)?

Yours, Christian Treczoks


User avatar
rp181
Respected Member
Posts: 395
Joined: Tue May 18, 2010 12:25 am
Contact:

Post by rp181 »

You don't have to keep channels open. Every time you send a value on a channel, the channel is opened, the data is sent, and the channel is closed. Only streaming channels stay open, or channels when using transactions.

Why not use a channel? The sender doesn't have to constantly send the data, but only when it needs it. For example, the master thread can request the data from the slave thread when it needs it.

Code: Select all

void master(chan c){
	unsigned token,temp;
	while(1){		
		//do stuff
		if(condition){
			c <: token;
			c :> temp;
		}
	}
}

void slave(chan c){
	unsigned token,temp;
	while(1){
		select{
			case c :> token:
				c <: temp;
				break;
			default:
				//do stuff, like sample the temperature
				break;
		}
	}
}
The slave thread will constantly execute the default block until the master sends a request for data, which the slave thread can then send. This way, it is entirely up to the master thread when the channel is used, and nothing is needlessly blocked.
lokesh327
Member++
Posts: 29
Joined: Wed Feb 06, 2013 2:24 pm

Post by lokesh327 »

It might be also due to same variable is used in two process, try to check swlock or hwlock and use it. might help you
Treczoks
Active Member
Posts: 38
Joined: Thu Mar 21, 2013 11:18 am
Contact:

Post by Treczoks »

Hi, rp181,
rp181 wrote:You don't have to keep channels open. Every time you send a value on a channel, the channel is opened, the data is sent, and the channel is closed. Only streaming channels stay open, or channels when using transactions.
Why not use a channel? The sender doesn't have to constantly send the data, but only when it needs it. For example, the master thread can request the data from the slave thread when it needs it.
Weeeeell, In my case, the data generating process is running a damn tight loop in realtime, and it was really, really hard to get there. Even having to monitor one channel will probably throw it far out of its timing specifications - select is a horrible cycle hog, and opening, using, closing a channel twice (to get the request and to provide the answer) will be an arms length of cycles, too.

Thats why I was aiming at "just reading" the data that was available in memory anyway.
XCs channels are nice idea for a lot of applications, but here we are talking screws & hammers.

Yours, Christian Treczoks
Treczoks
Active Member
Posts: 38
Joined: Thu Mar 21, 2013 11:18 am
Contact:

Post by Treczoks »

Hi, Lokesh327,
lokesh327 wrote:It might be also due to same variable is used in two process, try to check swlock or hwlock and use it. might help you
Indeed I intend to use a variable in two different processes. One process does read/write access, and the other one occasional read accesses. I already looked into swlock and hwlock, but they are avaiable in C only, and the manual warns of using them in conjunction with XC.

Yours, Christian Treczoks
User avatar
Ross
XCore Expert
Posts: 962
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

Treczoks wrote:Select is a horrible cycle hog
I'm afraid I completely disagree with this statement, a optimised select statement in a while(1) with a default case will compile to two instructions (setsr and clrsr - to turn core events on and off). The compiler is pretty good at pulling the setup for a select out of a while(1).
Treczoks wrote: and opening, using, closing a channel twice (to get the request and to provide the answer) will be an arms length of cycles, too.
As suggested, you can use a streaming channel especially if the cores on on the same tile: Input and outputs compile to a single instruction.

And if you really, really, really, can't afford these instructions use a line of inline asm to share some memory.
Treczoks
Active Member
Posts: 38
Joined: Thu Mar 21, 2013 11:18 am
Contact:

Post by Treczoks »

Ross wrote:
Treczoks wrote:Select is a horrible cycle hog
I'm afraid I completely disagree with this statement, a optimised select statement in a while(1) with a default case will compile to two instructions (setsr and clrsr - to turn core events on and off). The compiler is pretty good at pulling the setup for a select out of a while(1).
OK, if you say so. I've experienced it different, though, and it took quite some effort to beat the select into obedience.
I guess that the truth is somewhere in the middle grounds - for some constructs it might do better that for others. Do you have some tricks to share, e.g. "best practices with select", or "how not to use the select statement"?
Ross wrote:And if you really, really, really, can't afford these instructions use a line of inline asm to share some memory.
I know that you really love your channels at XMOS1. But they are no cure-it-alls.
Basically, I'm just wondering why a "one process writes, N processes read" model is so actively discouraged by the toolset, and suspected a technical reason as in "A memory cell just written by process A cannot be read by process B in the next cycle" or something like that.

Yours, Christian Treczoks

1Even more reason to actually document them better - see my other thread http://www.xcore.com/forum/viewtopic.php?f=3&t=2219
User avatar
Berni
Respected Member
Posts: 363
Joined: Thu Dec 10, 2009 10:17 pm
Contact:

Post by Berni »

There is a way to trick it in to reading another variable by using C pointers to point at the array.

So put a .c file in your project and make two subroutines in it. The first subrutine you call from the thread that writes the array. When you pass the array to the subrutine it will get it in the form of a pointer. Write that pointer down to a pointer variable at the top of the C code. Then when you want to read from the array call another subrutine that grabs the value from where that pointer is pointing and passes it back to your XC code.
User avatar
segher
XCore Expert
Posts: 844
Joined: Sun Jul 11, 2010 1:31 am
Contact:

Post by segher »

Treczoks wrote:and suspected a technical reason as in "A memory cell just written by process A cannot be read by process B in the next cycle" or something like that.
There is no such restriction.

In XC separate threads ("things inside a par") are *completely* separate.
That is rather fundamental in the language design. It has the disadvantage
that you cannot share memory between threads; it also has many advantages
in how the compiler can manipulate your code, and prove things about your
code. It isn't very often something that gets in your way, because it is *faster*
to pass data via a channel than it is to pass it through memory.
User avatar
Ross
XCore Expert
Posts: 962
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

segher wrote:it also has many advantages
in how the compiler can manipulate your code, and prove things about your
code.
And scaling to multiple tiles "just works" ;)
Post Reply