Calculating number of chanends

Technical questions regarding the xTIMEcomposer, xSOFTip Explorer and Programming with XMOS.
User avatar
Respected Member
Posts: 319
Joined: Wed Apr 25, 2012 8:52 pm

Calculating number of chanends

Postby aclassifier » Fri Feb 10, 2017 8:43 pm

How is number of chanends calculated?

Is there any trace of this calculation any place?

Is there any way to reason (tune) to minimize the number of chanends, provided the number of tasks and communication routes are the same?

The linker/mapper tells me I have 31 chanends. When I add a channel I get two more chanends, up to 33 ("FAILED"). If I add an interface I get two more. The interface ._chan channels are visible in the map file, but I can't find the c_mychan chans (4 channels). Since channels are handles to shared variables I guess scheduling and placement on cores come into the formula, ie. combinable and distributable. It didn't look like notifications use any more channels, as I assume they're "reused" back and forth. It also looks like there are som system channels there, like

Code: Select all

.text                _write_periph_32_on_chanend
.cp.rodata           chanends_to_setup             __sodChan

Update 14Feb2017: In the xTIMEcomposer User Guide (XM009801A) chapter 25.1 ("Redirect stdout and stderr to the xTAG") I read that a printf may be used "on any core at the same time. This usage results in a single channel end being allocated on each tile on which data is output." (See User Guide). Observe: per tile, not per core.

I found some info here: viewtopic.php?f=26&t=3512&p=22445&hilit=number+of+chanends#p22445 - but the formula is not there.

---- Aside ----
When I reduced these two interfaces

Code: Select all

typedef interface lib_startkit_adc_commands_if {
    [[guarded]] void trigger (void);
    [[guarded]] [[clears_notification]] {unsigned int, unsigned int} read (unsigned short adc_val[NUM_STARTKIT_ADC_INPUTS]);
    [[notification]] slave void complete (void);
} lib_startkit_adc_commands_if;

Code: Select all

typedef interface i2c_external_commands_if {
    [[clears_notification]] i2c_temps_t read_temperature_ok (void);
    [[notification]] slave void notify (void);
    void command (const i2c_command_external_t command);
} i2c_external_commands_if;

with these two (since it was ok to block on the calls):

Code: Select all

typedef interface lib_startkit_adc_commands_if {
    {unsigned int, unsigned int} get (unsigned short adc_val[NUM_STARTKIT_ADC_INPUTS]);
} lib_startkit_adc_commands_if;

Code: Select all

typedef interface i2c_external_commands_if {
    i2c_temps_t read_temperatures_ok (const i2c_command_external_t command);
} i2c_external_commands_if;

I got a reduction in chanends of 5 (five!). The first was used by one client and the second by two:

Code: Select all

[[combinable]] on tile[0].core[4]: i2c_external_server
    on tile[0].core[0]: [[combinable]] temperature_heater_controller
    on tile[0].core[0]: [[combinable]] buttons_and_display_handler (here..)

on tile[0]: my_startKIT_adc_client (free core) (not combinable since it contians a nested select)
    on tile[0].core[0]: [[combinable]] buttons_and_display_handler (..and here)

I'm 99.9 % certain my observation is right. If in doubt and it's important, ask me to redo since I have the commits. (But Im a little afraid of (g)it..). I really like xC, just imagine what detail on concurrency it hides! I am impressed.

Who is online

Users browsing this forum: No registered users and 139 guests