Thanks all for the replies.
Looking at the L and G clock frequency control documents is scary, they are so different.
I guess I'll have to be content with the 1 clock jitter in my experiments I have no way to look at what is happening on actual pins in that detail.
I'll be trying some experiments with cranking up the reference clock to equal the core clock later today.
According to the clock frequency document this is possible on the G devices. However I seem to remember a post in a thread some where that said on G devices the ref clock could only go to half the system clcock.
Also on my experiment list is to check out the effects of divide and mod. David May did hint that these may cause execution jitter of other threads.
Several questions about XMOS
-
- Respected Member
- Posts: 296
- Joined: Thu Dec 10, 2009 10:33 pm
-
- XCore Expert
- Posts: 844
- Joined: Sun Jul 11, 2010 1:31 am
Oh? Details vary a bit, but they are quite the same in principle.Heater wrote:Looking at the L and G clock frequency control documents is scary, they are so different.
That might well not work, as you say; I suggested clocking the core clock at the same as your ref clock,I'll be trying some experiments with cranking up the reference clock to equal the core clock later today.
not the other way around. That might not be fast enough for your application, but it's good for your
experiments.
Only other threads that use the division coprocessor as well. A division takes 32 cycles in there, notAlso on my experiment list is to check out the effects of divide and mod. David May did hint that these may cause execution jitter of other threads.
pipelined; any following division (from another thread, or the same thread) will have to wait until it's
done. Usually not a problem, code that cares about cycle counting usually needs to run very fast,
and very fast code shouldn't use integer division, since it's slow no matter what.
-
- Respected Member
- Posts: 296
- Joined: Thu Dec 10, 2009 10:33 pm
I'm not having much luck with this. I have been playing with changing the system and reference frequencies in my .xn file but whatever I do the results come out the same.
Code: Select all
<Node Id="0" Type="XS1-G4B" Oscillator="20MHz" SystemFrequency="100MHz" ReferenceFrequency="100MHz">
-
- Respected Member
- Posts: 296
- Joined: Thu Dec 10, 2009 10:33 pm
The code below is my experiment to show the effect of the use of divides in threads causing execution jitter.
There are only four threads running.
Results in this:
Removing the divides from either thread restores determinism.
Still not having any luck changing SystemFrequency of ReferenceFrequency in the .xn file.
There are only four threads running.
Code: Select all
#include <stdio.h>
#include <platform.h>
int a = 100;
int b = 10;
int c;
void calc_thread()
{
timer tmr;
unsigned t;
unsigned period;
unsigned loops;
period = 100000000;
tmr :> t;
while (1)
{
tmr when timerafter(t) :> void;
t += period;
for (loops = 0; loops < 1000000; loops++)
{
c = a / b;
c = c * b;
c = a / b;
c = c * b;
c = a / b;
c = c * b;
c = a / b;
c = c * b;
c = a / b;
c = c * b;
}
}
}
void waste_thread()
{
while(1)
{
}
}
int x = 100;
int y = 10;
int f;
void timed_thread()
{
long startTime, endTime;
timer t;
printf ("Determinism test:\n");
while (1)
{
// Start benchmark timer
t :> startTime;
f = x / y;
f = f * y;
f = x / y;
f = f * y;
f = x / y;
f = f * y;
// Stop benchmark timer
t :> endTime;
printf ("Run time = %d timer ticks\n", endTime - startTime);
}
}
int main()
{
par
{
on stdcore[0]: timed_thread();
on stdcore[0]: calc_thread();
on stdcore[0]: waste_thread();
on stdcore[0]: waste_thread();
}
return 0;
}
Code: Select all
Run time = 107 timer ticks
Run time = 96 timer ticks
Run time = 96 timer ticks
Run time = 96 timer ticks
Run time = 106 timer ticks
Run time = 96 timer ticks
Run time = 96 timer ticks
Run time = 96 timer ticks
Run time = 106 timer ticks
...
Still not having any luck changing SystemFrequency of ReferenceFrequency in the .xn file.
-
- Experienced Member
- Posts: 69
- Joined: Mon May 17, 2010 10:19 am
The first thing to check is that you can successfully alter them independently - try flashing LEDs using first instruction cycles then a timer to check that the flash speed changes when you change the appropriate clock rates.Heater wrote:Still not having any luck changing SystemFrequency of ReferenceFrequency in the .xn file.
-
- XCore Addict
- Posts: 165
- Joined: Wed Feb 10, 2010 2:32 pm
On an XS1-G device you should ensure that the reference frequency is at least half of the system frequency. So in the example above you should either set the System Freq to 200, or the ref freq to 50MHz.Heater wrote:Code: Select all
<Node Id="0" Type="XS1-G4B" Oscillator="20MHz" SystemFrequency="100MHz" ReferenceFrequency="100MHz">
When you say that you are having trouble with it, does that mean that the results you've posted are not using those figures? If so, what are the settings you are using for the clock?
-
- XCore Addict
- Posts: 165
- Joined: Wed Feb 10, 2010 2:32 pm
@Heater,
Thanks for posting the code example. A couple of points
1. In the waste threads, can you put the thread into fast mode. These threads may not be issuing instructions otherwise
2. timed_thread and calc_thread both use the divider. Since there is only 1 divide unit that is shared across all threads on the XCore, they will have to arbitrate for the divide unit and you may well see odd behaviour. I would avoid all divide (& rem) operations in all threads when you are performing timing checks, although if you only use them in 1 thread, then the performance will be predictable.
3. printf(). This puts the XCore into debug mode. This means that all the threads stop their current execution, then thread 0 starts executing the debug monitor code and, relatively slowly, performs the printf. When the print stops, the threads return to executing their code. So if you perform a print operation all timing bets are off. To avoid this, create an array of results, then print all of the results from the array when all the iterations of the test have completed.
Thanks for posting the code example. A couple of points
1. In the waste threads, can you put the thread into fast mode. These threads may not be issuing instructions otherwise
Code: Select all
set_thread_fast_mode_on();
3. printf(). This puts the XCore into debug mode. This means that all the threads stop their current execution, then thread 0 starts executing the debug monitor code and, relatively slowly, performs the printf. When the print stops, the threads return to executing their code. So if you perform a print operation all timing bets are off. To avoid this, create an array of results, then print all of the results from the array when all the iterations of the test have completed.
-
- Respected Member
- Posts: 296
- Joined: Thu Dec 10, 2009 10:33 pm
@m_y and Woody,
Turns out I have been having a problem with Eclipse. Whilst busy changing from Debug to Release builds I ended up changing the .xn file, rebuilding the correct version but then running the wrong one.
God I hate IDE's.
Working from the command line tools, so we know where we are, confirms that changing SystemFrequency and ReferenceFrequency in the .xn does indeed work and changes by test results as expected. With one strange result:
Seems a Sys Clock of 400 with Ref Clock of 400 and 100 are the same but the mapper issues no warning/error about that. Both give my jitter like so:
I can see that if I change all divides in my calc_thread the jitter in the timed thread disappears.
@Woody,
I can see no effect when putting my waste_threads into fast mode. But as far as I can tell neither should I. If I understand correctly fast mode only forces threads to issue instructions while they
are waiting on a port/timer/channel instead of sleeping. The waste threads do no such waiting.
Further I would expect fast mode to only have an effect with more than 4 threads when there are actually free cycles for other threads to run when one is sleeping.
I my tests there is no timing going on across printf's so I'm not sure that all timing bets are off in this case.
Turns out I have been having a problem with Eclipse. Whilst busy changing from Debug to Release builds I ended up changing the .xn file, rebuilding the correct version but then running the wrong one.
God I hate IDE's.
Working from the command line tools, so we know where we are, confirms that changing SystemFrequency and ReferenceFrequency in the .xn does indeed work and changes by test results as expected. With one strange result:
Code: Select all
Sys Clk Ref Clk Time (secs)
400 400 10
400 300 Not achievable
400 200 5
400 150 Not achievable
400 100 10
400 50 20
Code: Select all
Run time = 105 timer ticks
Run time = 96 timer ticks
Run time = 96 timer ticks
Run time = 96 timer ticks
Run time = 106 timer ticks
Run time = 96 timer ticks
...
I can see that if I change all divides in my calc_thread the jitter in the timed thread disappears.
@Woody,
I can see no effect when putting my waste_threads into fast mode. But as far as I can tell neither should I. If I understand correctly fast mode only forces threads to issue instructions while they
are waiting on a port/timer/channel instead of sleeping. The waste threads do no such waiting.
Further I would expect fast mode to only have an effect with more than 4 threads when there are actually free cycles for other threads to run when one is sleeping.
Yes. Here I am basically trying to prove that that is true:) Seems to be so. Removing the divides from the calc_thread restores determinism to the timed_thread as advertised.2. timed_thread and calc_thread both use the divider. Since there is only 1 divide unit that is shared across all threads on the XCore, they will have to arbitrate for the divide unit and you may well
see odd behaviour. I would avoid all divide (& rem) operations in all threads when you are performing timing checks, although if you only use them in 1 thread, then the performance will be
predictable.
I'm glad you mentioned that. I have been wondering what goes on when I do a printf. And what happens when many threads do a printf etc.3. printf(). This puts the XCore into debug mode....
I my tests there is no timing going on across printf's so I'm not sure that all timing bets are off in this case.
-
- XCore Addict
- Posts: 165
- Joined: Wed Feb 10, 2010 2:32 pm
1. I wasn't 100% sure that the compiler wouldn't work out it wasn't doing anything and wait. I just wanted to ensure that this wasn't causing a problem. Obviously not.
3. You may be right that it might not cause you a problem. Similar reason to above, but I sometimes see unexpected (to me) artifacts from printing. Worth being aware of anyway.
I think the errors/warnings from the freq setting are issued at slightly different times to when you might expect. I'll leave m_v to explain this.
3. You may be right that it might not cause you a problem. Similar reason to above, but I sometimes see unexpected (to me) artifacts from printing. Worth being aware of anyway.
I think the errors/warnings from the freq setting are issued at slightly different times to when you might expect. I'll leave m_v to explain this.
-
- Respected Member
- Posts: 296
- Joined: Thu Dec 10, 2009 10:33 pm
Woody,
I get this error out of the mapper when setting a 300MHz ref clock.
Setting a 100MHz ref is error/warning free of course.
Setting a 400MHz results in only a warning which looks OK:
However my timing results come out exactly the same as for 100MHz!!!
I get this error out of the mapper when setting a 300MHz ref clock.
Code: Select all
Invoking: Mapper/Linker
xcc -Werror=timing-syntax -o "determinism_test.xe" ./main.o ../XC-1A.xn
../XC-1A.xn:15 Warning: XN11137 300000000Hz reference frequency for node "0" could not be achived. Using 200000000Hz.
../XC-1A.xn:15 Warning: XN11137 300000000Hz reference frequency for node "0" could not be achived. Using 200000000Hz.
xmap: Warning: Node "0" does not have 100Mhz reference clock.
Setting a 400MHz results in only a warning which looks OK:
Code: Select all
xmap: Warning: Node "0" does not have 100Mhz reference clock.