253 lines · 10.9 KB · C#
RawDownload
//******************************************************************************************************//  OptimizationOptions.cs - Gbtc////  Copyright © 2016, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the MIT License (MIT), the "License"; you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/MIT////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  10/27/2016 - Steven E. Chisholm//       Generated original version of source code.////****************************************************************************************************** using System;using System.Collections.Generic;using System.Diagnostics;using GSF.Configuration;using GSF.Diagnostics; namespace GSF{      /// <summary>    /// This class will contain various optimizations that can be enabled in certain circumstances     /// through the SystemSettings. Since this framework is used in many settings, for stability    /// reasons, tradeoffs are made. This gives the users opportunities to enable/disable certain    /// optimizations if for some reason they cause adverse effects on their system.    /// </summary>    public static class OptimizationOptions    {        /// <summary>        /// The routing method to use.        /// </summary>        public enum RoutingMethod        {            /// <summary>            /// The default method of routing            /// </summary>            Default,             /// <summary>            /// A custom implementation that sacrifices overall latency for lower CPU utilization.            /// </summary>            HighLatencyLowCpu,         }         private static readonly LogPublisher Log = Logger.CreatePublisher(typeof(OptimizationOptions), MessageClass.Framework);         /// <summary>        /// Eliminates certain async queues in the phasor protocol parsing.         /// </summary>        public static bool DisableAsyncQueueInProtocolParsing { get; private set; } = false;         /// <summary>        /// Uses dedicated threads instead of LongSynchronizedOperations in certain cases.        /// </summary>        public static bool PreferDedicatedThreads { get; private set; } = false;         /// <summary>        /// Specifies the desired routing method.        /// </summary>        public static RoutingMethod DefaultRoutingMethod { get; private set; } = RoutingMethod.Default;         /// <summary>        /// Specifies a routing latency if the routing method recgonizes this.        /// </summary>        public static int RoutingLatency { get; private set; } = 50;         /// <summary>        /// Specifies the target number of measurements per batch operation.        /// </summary>        public static int RoutingBatchSize { get; private set; } = 200;         /// <summary>        /// Specifies that threadpool monitoring will be enabled.        /// </summary>        public static bool EnableThreadPoolMonitoring { get; private set; } = false;         /// <summary>        /// Specifies that the threadpool monitor should also dump the stack trace of all thread.        /// </summary>        public static bool EnableThreadStackDumping { get; private set; } = false;         static OptimizationOptions()        {            string setting = string.Empty;            try            {                ConfigurationFile configFile = ConfigurationFile.Current;                CategorizedSettingsElementCollection systemSettings = configFile.Settings["systemSettings"];                systemSettings.Add("OptimizationsConnectionString", "", "Specifies which optimizations to enable for the system.");                setting = systemSettings["OptimizationsConnectionString"].ValueAsString("");                Dictionary<string, string> optimizations = setting.ParseKeyValuePairs();                 LoadThreadPoolMonitoring(optimizations);                LoadPreferDedicatedThreads(optimizations);                LoadAsyncQueueInProtocolParsing(optimizations);                LoadProcessorAffinity(optimizations);                LoadRoutingTable(optimizations);            }            catch (Exception ex)            {                Log.Publish(MessageLevel.Warning, "Could not parse Optimization Settings", setting, null, ex);            }            ThreadPoolMonitor.Initialize();        }         private static void LoadThreadPoolMonitoring(Dictionary<string, string> optimizations)        {            if (optimizations.ContainsKey("EnableThreadPoolMonitoring"))            {                Log.Publish(MessageLevel.Info, "Enable Optimization", "EnableThreadPoolMonitoring");                EnableThreadPoolMonitoring = true;            }            if (optimizations.ContainsKey("EnableThreadStackDumping"))            {                Log.Publish(MessageLevel.Info, "Enable Optimization", "EnableThreadStackDumping");                EnableThreadStackDumping = true;            }        }         private static void LoadAsyncQueueInProtocolParsing(Dictionary<string, string> optimizations)        {            if (optimizations.ContainsKey("DisableAsyncQueueInProtocolParsing"))            {                Log.Publish(MessageLevel.Info, "Enable Optimization", "DisableAsyncQueueInProtocolParsing");                DisableAsyncQueueInProtocolParsing = true;            }        }         private static void LoadPreferDedicatedThreads(Dictionary<string, string> optimizations)        {            if (optimizations.ContainsKey("PreferDedicatedThreads"))            {                Log.Publish(MessageLevel.Info, "Enable Optimization", "PreferDedicatedThreads");                PreferDedicatedThreads = true;            }        }         private static void LoadProcessorAffinity(Dictionary<string, string> optimizations)        {            if (optimizations.ContainsKey("ProcessorAffinity"))            {                ulong value;                if (ulong.TryParse(optimizations["ProcessorAffinity"], out value))                {                    if (value > 0)                    {                        Process.GetCurrentProcess().ProcessorAffinity = (IntPtr)(long)value;                        Log.Publish(MessageLevel.Info, "Enable Optimization", "Processor Affinity set to " + Process.GetCurrentProcess().ProcessorAffinity.ToInt64().ToString("X"));                    }                    else                    {                        Log.Publish(MessageLevel.Warning, "Parsing Error", "Processor Affinity cannot be zero");                    }                }                else                {                    Log.Publish(MessageLevel.Warning, "Parsing Error", "Unrecognized option for ProcessAffinity: " + optimizations["ProcessorAffinity"]);                }            }        }         private static void LoadRoutingTable(Dictionary<string, string> optimizations)        {            if (optimizations.ContainsKey("RoutingMethod"))            {                string method = optimizations["RoutingMethod"];                if (method.Equals("RouteMappingHighLatencyLowCpu", StringComparison.CurrentCultureIgnoreCase))                {                    int latency = -1;                     if (optimizations.ContainsKey("RoutingLatencyMS"))                    {                        string latencyString = optimizations["RoutingLatencyMS"];                        if (int.TryParse(latencyString, out latency))                        {                            if (latency < 1 || latency > 500)                            {                                Log.Publish(MessageLevel.Info, "Routing Table", "Invalid range of routing latency. Defaulting to 10 ms. (Range: 1ms to 500ms)", "Value: " + latencyString);                                latency = 10;                            }                        }                        else                        {                            Log.Publish(MessageLevel.Info, "Routing Table", "Could not parse latency value. Defaulting to 10 ms.", "Value: " + latencyString);                            latency = 10;                        }                    }                    else                    {                        latency = 10;                    }                     int countPerBatch = -1;                     if (optimizations.ContainsKey("RoutingBatchSize"))                    {                        string countPerBatchString = optimizations["RoutingBatchSize"];                        if (int.TryParse(countPerBatchString, out countPerBatch))                        {                            if (countPerBatch < 20 || countPerBatch > 10000)                            {                                Log.Publish(MessageLevel.Info, "Routing Table", "Invalid RoutingBatchSize. Defaulting to 200. (Range: 20 to 10000)", "Value: " + countPerBatch);                                countPerBatch = 200;                            }                        }                        else                        {                            Log.Publish(MessageLevel.Info, "Routing Table", "Could not parse RoutingBatchSize. Defaulting to 200.", "Value: " + RoutingBatchSize);                            countPerBatch = 200;                        }                    }                    else                    {                        countPerBatch = 200;                    }                      Log.Publish(MessageLevel.Info, "Routing Table", "Using RouteMappingHighLatencyLowCpu.", "Latency: " + latency.ToString() + " Batch Size: " + countPerBatch);                     DefaultRoutingMethod = RoutingMethod.HighLatencyLowCpu;                    RoutingLatency = latency;                    RoutingBatchSize = countPerBatch;                }                else if (method.Equals("Default", StringComparison.CurrentCultureIgnoreCase))                {                    Log.Publish(MessageLevel.Info, "Routing Table", "Using the default routing table.");                }                else                {                    Log.Publish(MessageLevel.Warning, "Routing Table", "Specified routing method is not recognized. The default will be used.", "Value: " + method);                }            }            else            {                Log.Publish(MessageLevel.Info, "Routing Table", "Method not specified, using the default routing table.");            }        }    }}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t