Since the Matlab Engine is a non-thread-safe shared environment for computation, some special considerations apply when running multiple instances of 1258.
- Note that running an Automation Server can signficantly improve performance on Windows - see the last section of this page.
The Matlab Engine is not thread-safe. That is, it may not be called concurrently from multiple threads. Therefore, 1258 sets
F_NO_CONCURRENCY, forcing all 1258 processes to run in the same thread, and thus all calls to the Matlab Engine from separate instances of 1258 are interleaved rather than concurrent.
- It may be safe to call the Engine interleaved from multiple threads - actual thread identity is immaterial on some platforms - but this is not relevant here. The only concern, here, is avoiding concurrent calls.
F_NO_CONCURRENCY causes segmentation faults or data corruption on Windows (messages like "Forced Assertion "Corrupted memory block found""). Interestingly , using engineOpenSingleUse() (causing one Engine to open for each 1258 instance) does not fix this, implying that some data is common to the single-use engines.
F_NO_CONCURRENCY may also cause aborts on Linux, but this stage is never reached. Apparently (and this is understood from the documentation, as well) 1258 communicates with the Engine via a pipe on Linux; concurrent write/reads to the same pipe seemingly corrupt the instructions to the Engine long before we have a change to get any binary-level corruption (messages such as "Unable to read MAT from STDIO. Unknown Error.).
However, multiple instances of 1258 can safely use a single Matlab Engine, on both Windows and Linux. The calls are interleaved from each instance, but never concurrent. One concern is that some data are, thus, shared between 1258 instances (for instance, the state of Matlab's RNGs that lie behind the calls rand() and randn()). Special care must be taken by the 1258 author if such data are used (for instance, pop() and push() the state of the RNG as you enter and leave events).
To see this effect in action, execute
at the Matlab Prompt. You will see conflict behaviour on Windows and Linux, with the first random number being doled out to the first 1258 process, the second to the second, the third to the first, etc.
- On Windows, we call engOpen() to connect to the Matlab Engine. If an instance is already open, we will be connected to this one. Thus, only one instance is started for all 1258 processes.
- On Linux, we store the handle to the engine at module-level in 1258. Thus, subsequent instances use the Engine already opened by the first instance. Interleaved calls are guaranteed by
F_NO_CONCURRENCY, and behaviour is as for windows.
When running Concerto, the situation is slightly different depending on platform.
On Windows, multiple Voices can still use the same Engine. The Matlab Engine does appear to be "process-safe", in that no attempt to call it concurrently from multiple Voices has yet resulted in data corruption or segmentation faulting. However, the same care must be taken over shared data as described in the above section, since the Engine is still shared.
On Linux, multiple Voices cannot use the same Engine, since the mechanism for connecting with the Engine is quite different. Thus, on Linux, one Engine will start for each Voice. There are, therefore, no multiple Voice concerns on Linux (but the cost is slower startup).
To see this effect in action, execute
at the Matlab Prompt. You will see conflict behaviour on Windows, but no conflict behaviour on Linux. On Windows, the doling out behaviour is chaotic, since the two instances are not synchronised.
- It seems odd that the Engine be process-safe but not thread-safe, as it implies either than Matlab mutually excludes entry from different handles only if they are held by different processes (unlikely, but possible) or that the non-thread-safe code is built into 1258. It would probably make perfect sense if we knew the internals, but we don't. One clue is that multiple instances under Concerto will not use more than one processor's worth of CPU time, suggesting that they are effectively operating interleaved, whatever the mechanism.
Speeding Things Along
The worst thing about 1258 is waiting for the Matlab Engine to start when you launch your System. On Windows, this wait can be reduced very substantially by starting a Matlab Automation Server before you start. This can be done by execution
matlab /Automation at the Command Prompt. 1258 will use a running Automation Server if one is present; if not, it will open a new Matlab Engine instance, and close it when it is finished with.
Unfortunately, there is no equivalent support on Linux.
- One gotcha with this is that the open Automation Server may cache your script, and not realise when it changes. Try opening, and editing, your script through the Automation Server's own Matlab Editor - this will ensure it always knows when the script changes.
Numeric Storage Format
1258 sets complex storage format and array order flags when calling EVENT_GENERIC_STRUCTURE_SET and EVENT_GENERIC_STRUCTURE_GET. This will affect the generic structure interface for some data objects. For instance,
std/data/numeric will not return, and should not be passed, string parts indicating these structure aspects.