public void Initialize() { if (_isInitialized) { DisposeRuntime(); } _isInitialized = true; // Check limits if (_outputInitializer.Count > ushort.MaxValue * Tools.NB_BITS_PER_BYTE) // To increase this limit change ushort type of maskLength and index into PulseSource { throw new OverflowException($"Max output capacity reached: Max={sizeof(ushort) * Tools.NB_BITS_PER_BYTE} NbOutputs={_outputInitializer.Count}"); } // First prepare indices PrepareIndices(_outputInitializer, _inputInitializer); // Compute the memory length. // 1. We use 1 bit to flag a subscribe var flagsSize = Ceiling(_outputInitializer.Count / Tools.NB_BITS_PER_BYTE, sizeof(uint)); // 2. For subscribers // 2.1 state size var pulseProbeSize = sizeof(PulseProbe) * _outputInitializer.Count; // 3. For producer // 3.1 structure layout size var pulseSourceSize = sizeof(PulseSource) * _inputInitializer.Count; // 3.2 pImpulseMask size var pulseMasksSizes = _inputInitializer.Sum(p => p.Value.MaskLength); var totalSize = flagsSize + pulseProbeSize + pulseSourceSize + pulseMasksSizes; // Allocate the memory _globalMemory = Marshal.AllocHGlobal(totalSize); // Prepare memory var ptr = (byte *)_globalMemory; //var pFlags = ptr; //var pPulseProbe = (PulseProbe*)(ptr + coilSize); //var pPulseMetrics = (PulseMetrics*)(ptr + coilSize + galvanometersSize); //var pPulseSource = (PulseSource*)(ptr + coilSize + galvanometersSize + galvanometerStatesSize); //var pPulseMask = ptr + coilSize + galvanometersSize + galvanometerStatesSize + currentFlowsSize; var pPulseSource = (PulseSource *)ptr; var pFlags = ptr + pulseSourceSize; var pPulseMask = ptr + pulseSourceSize + flagsSize; var pPulseProbe = (PulseProbe *)(ptr + pulseSourceSize + flagsSize + pulseMasksSizes); InstallFlags(pFlags, flagsSize); InstallPulseProbes(pPulseProbe, pFlags, _outputInitializer); InstallPulseSources(pPulseSource, pFlags, pPulseMask, _inputInitializer); _runTimes.AddRange(_inputInitializer.Select(p => p.Value.CreateRuntime())); _queue.SetCapacity(_runTimes.Count); _queue.Reset(); #region Build Report _reports.Clear(); _reports.AppendLine("=== Initialize"); _reports.AppendLine($"Flags Size: {flagsSize / 1000.0} Ko"); _reports.AppendLine($"PulseProbe Size: {pulseProbeSize / 1000.0} Ko"); _reports.AppendLine($"PulseSource Size: {pulseSourceSize / 1000.0} Ko"); _reports.AppendLine($"PulseMasks Size: {pulseMasksSizes / 1000.0} Ko"); _reports.AppendLine("--------------------------------"); _reports.AppendLine($"Total Size: {totalSize / 1000.0} Ko"); _reports.AppendLine("==="); #endregion }