コード例 #1
0
        private void InitializeEndpoint()
        {
            // Get host addresses for specified host
            var addresses = Dns.GetHostAddresses(_host);

            if (addresses.Length == 0)
            {
                CH.Exit("Failure", "Unable to retrieve address from specified host.");
            }

            // Loop through addresses and use the first IPV4 address
            for (var i = 0; i < addresses.Length; i++)
            {
                if (addresses[i].AddressFamily == AddressFamily.InterNetwork)
                {
                    _endpoint = new IPEndPoint(addresses[i], _port);
                    break;
                }
            }

            if (_endpoint == null)
            {
                CH.Exit("Failure", "Unable to resolve specified host to a valid IP address.");
            }
        }
コード例 #2
0
        private void GenerateGraph()
        {
            // Setup the graph pane
            var pane = new GraphPane(new RectangleF(0, 0, 1024, 480), "HashPeak", "GPU engine clock (MHz)", "Hashrate (khash/s)");

            pane.Y2Axis.Title.Text = "Hardware errors";

            // Add the hashrate curve
            pane.AddCurve("Hashrate", _hashRatePoints, Color.Green, SymbolType.None);
            ((LineItem)pane.CurveList[0]).Line.Width       = 2.0F;
            ((LineItem)pane.CurveList[0]).Line.IsAntiAlias = true;

            // Add the HW errors curve
            pane.AddCurve("Hardware errors", _hwErrorPoints, Color.Red, SymbolType.None);
            ((LineItem)pane.CurveList[1]).Line.Width       = 2.0F;
            ((LineItem)pane.CurveList[1]).Line.IsAntiAlias = true;
            pane.CurveList[1].IsY2Axis = true;
            pane.Y2Axis.IsVisible      = true;

            // Setup scales
            pane.XAxis.Scale.Min  = _minGpuClock;
            pane.XAxis.Scale.Max  = _maxGpuClock;
            pane.Y2Axis.Scale.Min = 0;

            // Save as PNG
            var bitmap = new Bitmap(1, 1);

            using (var g = Graphics.FromImage(bitmap))
                pane.AxisChange(g);

            try
            {
                pane.GetImage(true).Save(string.Format(GraphFilenameFormat, _host, _gpuId, _saveMemClock, _minGpuClock, _maxGpuClock, DateTime.Now.ToString("yyyyMMdd")), ImageFormat.Png);
            }
            catch (Exception)
            {
                CH.Exit("An error occurred while saving graph to file {0}. Is the file in use?", string.Format(GraphFilenameFormat, _host, _gpuId, _saveMemClock, _minGpuClock, _maxGpuClock, DateTime.Now.ToString("yyyyMMdd")));
            }
        }
コード例 #3
0
        private double GetStableHashRate()
        {
            var currentHashRate = 0d;
            var hashRateHistory = new List <double>();

            // Try for a maximum of AutoDelayMaxWaitSeconds seconds
            for (var i = 0; i < AutoDelayMaxWaitSeconds; i++)
            {
                System.Threading.Thread.Sleep(1000);

                var gpuResponse = Send <GpuResponse>(JsonConvert.SerializeObject(new Request {
                    Command = "gpu", Parameter = _gpuId.ToString(CultureInfo.InvariantCulture)
                }));
                if (gpuResponse.Gpu == null)
                {
                    CH.Exit("Failure", gpuResponse.Status[0].Msg);
                }

                currentHashRate = gpuResponse.Gpu[0].MhsXs * 1000;

                // Do we have enough samples?
                if (hashRateHistory.Count == StabilitySampleCount)
                {
                    if (HashRateIsStable(currentHashRate, hashRateHistory))
                    {
                        break;
                    }

                    // Remove the oldest sample
                    hashRateHistory.RemoveAt(0);
                }

                // Add a new sample
                hashRateHistory.Add(currentHashRate);
            }

            return(currentHashRate);
        }
コード例 #4
0
        public void ParseCommandLineArgs(string[] args)
        {
            var showHelp    = false;
            var delayString = "auto";

            // We're using Mono.Options to parse the command line arguments (see Options.cs)
            var os = new OptionSet
            {
                { "host=", "IP or hostname for miner API. Default: 127.0.0.1.", v => _host = v },
                { "port=", "Port number for miner API. Default: 4028.", (int v) => _port = v },
                { "gpu-id=", "GPU ID to work on. [required]", (int v) => _gpuId = v },
                { "min-gpu-clock=", "Lower limit of GPU engine clock frequency range to test. [required]", (int v) => _minGpuClock = v },
                { "max-gpu-clock=", "Upper limit of GPU engine clock frequency range to test. [required]", (int v) => _maxGpuClock = v },
                { "step=", "Number of MHz to increase GPU engine clock per iteration. Default 1.", (int v) => _step = v },
                { "delay=", "Seconds to wait between setting new clock and testing the hashrate. Default: auto (see README).", v => delayString = v },
                { "help", "Show this message and exit.", v => showHelp = v != null }
            };

            try
            {
                os.Parse(args);
            }
            catch (OptionException e)
            {
                CH.Exit(e.Message + Environment.NewLine + "Try `HashPeak --help' for more information.");
            }

            if (showHelp)
            {
                CH.ShowHelp(os);
            }

            // Validate parameter values and set defaults
            if (_host == null)
            {
                _host = "127.0.0.1";
            }
            if (_port < 0)
            {
                _port = 4028;
            }
            if (_gpuId < 0)
            {
                CH.Exit("The --gpu-id parameter is missing or invalid. Try `HashPeak --help' for more information.");
            }
            if (_minGpuClock < 0)
            {
                CH.Exit("The --min-gpu-clock parameter is missing or invalid. Try `HashPeak --help' for more information.");
            }
            if (_maxGpuClock < 0)
            {
                CH.Exit("The --max-gpu-clock parameter is missing or invalid. Try `HashPeak --help' for more information.");
            }
            if (_step < 0)
            {
                _step = 1;
            }

            if (delayString.ToLower() != "auto")
            {
                if (!int.TryParse(delayString, out _delay))
                {
                    CH.Exit("The --delay parameter is missing or invalid. The paramater must be either `auto' or a delay value in seconds. Try `HashPeak --help' for more information.");
                }

                if (_delay < 0)
                {
                    _delay = 20;
                }

                _autoDelayEnabled = false;
            }
        }
コード例 #5
0
        public T Send <T>(string request)
        {
            // Initialize the socket endpoint
            if (_endpoint == null)
            {
                InitializeEndpoint();
            }

            // Setup socket
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
            {
                SendTimeout    = 5000,
                ReceiveTimeout = 5000
            };
            var sb = new StringBuilder(256);

            try
            {
                // Connect to endpoint and send payload
                socket.Connect(_endpoint);
                socket.Send(Encoding.ASCII.GetBytes(request));

                // Receive response
                var buffer = new byte[65535];
                while (true)
                {
                    var len = socket.Receive(buffer, 65535, SocketFlags.None);
                    if (len < 1)
                    {
                        break;
                    }
                    sb.Append(Encoding.ASCII.GetString(buffer), 0, len);
                    if (buffer[len - 1] == '\0')
                    {
                        break;
                    }
                }

                // Tidy up
                socket.Shutdown(SocketShutdown.Both);
                socket.Close();
            }
            catch (Exception ex)
            {
                CH.Exit("Failure", ex.Message);
            }

            var response = sb.ToString();

            // The property name for the average Mhash varies depending on log interval. Normalize it to "MHS Xs".
            if (typeof(T) == typeof(GpuResponse))
            {
                response = Regex.Replace(response, "\"MHS [0-9]+s\"", "\"MHS Xs\"");
            }

            // Deserialize response
            var result = JsonConvert.DeserializeObject <T>(response);

            if (result == null)
            {
                CH.Exit("Failure", "Received unexpected response from API.");
            }

            return(result);
        }
コード例 #6
0
        public void Run()
        {
            // Query API for version number (verifies connectivity)
            CH.Write(string.Format(" - Connecting to API on {0}:{1}... ", _host, _port), ConsoleColor.White);
            var versionResponse = Send <VersionResponse>(JsonConvert.SerializeObject(new Request {
                Command = "version"
            }));

            CH.Write("Success", ConsoleColor.Green);
            CH.Write(string.Format(" ({0})" + Environment.NewLine, versionResponse.Status[0].Description), ConsoleColor.Gray);

            // The autoDelay feature doesn't make sense when running against cgminer due to the limited API hashrate accuracy
            if (_autoDelayEnabled && versionResponse.Status[0].Description.StartsWith("cgminer"))
            {
                _autoDelayEnabled = false;
                _delay            = 20;

                CH.Write(" - Detected cgminer. Forcing delay to 20 seconds." + Environment.NewLine, ConsoleColor.White);
            }

            // Verify that we have privileged access to the API
            CH.Write(" - Verifying priviliged access to API... ", ConsoleColor.White);
            var statusResponse = Send <StatusResponse>(JsonConvert.SerializeObject(new Request {
                Command = "privileged"
            }));

            if (statusResponse.Status[0].Status == "E")
            {
                CH.Exit("Failure", statusResponse.Status[0].Msg);
            }

            CH.Write("Success" + Environment.NewLine, ConsoleColor.Green);

            // Query API for the specified GPU id
            CH.Write(string.Format(" - Looking for GPU with id {0}... ", _gpuId), ConsoleColor.White);
            var gpuResponse = Send <GpuResponse>(JsonConvert.SerializeObject(new Request {
                Command = "gpu", Parameter = _gpuId.ToString(CultureInfo.InvariantCulture)
            }));

            if (gpuResponse.Gpu == null)
            {
                CH.Exit("Failure", gpuResponse.Status[0].Msg);
            }

            CH.Write("Success", ConsoleColor.Green);
            CH.Write(string.Format(" ({0} {1}/{2})" + Environment.NewLine, gpuResponse.Gpu[0].Status, gpuResponse.Gpu[0].GpuClock, gpuResponse.Gpu[0].MemoryClock), ConsoleColor.Gray);
            _saveMemClock = gpuResponse.Gpu[0].MemoryClock;
            _saveGpuClock = gpuResponse.Gpu[0].GpuClock;

            // TODO: Only proceed if card is "Alive"?

            CH.Write(Environment.NewLine + " Starting measurements." + Environment.NewLine + Environment.NewLine, ConsoleColor.White);

            // Setup
            _logFilename = string.Format(LogFilenameFormat, _host, _gpuId, _saveMemClock, _minGpuClock, _maxGpuClock, DateTime.Now.ToString("yyyyMMdd"));
            var peakHashRate  = 0d;
            var peakGpuClock  = 0;
            var hwErrorsTally = 0;
            var peakHwErrors  = 0;

            _hashRatePoints = new PointPairList();
            _hwErrorPoints  = new PointPairList();

            // Loop through GPU engine clock range
            for (var gpuClock = _minGpuClock; gpuClock <= _maxGpuClock; gpuClock += _step)
            {
                CH.Write(string.Format(" - Setting GPU engine clock to {0}... ", gpuClock), ConsoleColor.White);
                statusResponse = Send <StatusResponse>(JsonConvert.SerializeObject(new Request {
                    Command = "gpuengine", Parameter = _gpuId + "," + gpuClock
                }));
                if (statusResponse.Status[0].Status == "E" || statusResponse.Status[0].Status == "F")
                {
                    CH.Exit("Failure", statusResponse.Status[0].Msg);
                }
                CH.Write("Success" + Environment.NewLine, ConsoleColor.Green);

                double currentHashRate;
                if (_autoDelayEnabled)
                {
                    CH.Write(" - Waiting for hashrate to stabilize... ", ConsoleColor.White);
                    currentHashRate = GetStableHashRate();
                    CH.Write("Done", ConsoleColor.Green);
                    CH.Write(string.Format(" ({0} khash/s)" + Environment.NewLine, currentHashRate), ConsoleColor.Gray);
                }
                else
                {
                    // Wait _delay seconds and then take the measurement
                    // TODO: Wait longer the first time
                    CH.Write(string.Format(" - Waiting {0} seconds for hashrate to stabilize... ", _delay), ConsoleColor.White);
                    System.Threading.Thread.Sleep(_delay * 1000);
                    CH.Write("Done", ConsoleColor.Green);

                    gpuResponse = Send <GpuResponse>(JsonConvert.SerializeObject(new Request {
                        Command = "gpu", Parameter = _gpuId.ToString(CultureInfo.InvariantCulture)
                    }));
                    if (gpuResponse.Gpu == null)
                    {
                        CH.Exit("Failure", gpuResponse.Status[0].Msg);
                    }

                    currentHashRate = gpuResponse.Gpu[0].MhsXs * 1000;
                    CH.Write(string.Format(" ({0} khash/s)" + Environment.NewLine, currentHashRate), ConsoleColor.Gray);
                }

                // Check for hashrate peak
                if (currentHashRate > peakHashRate)
                {
                    peakHashRate = currentHashRate;
                    peakGpuClock = gpuClock;
                }

                // Calculate HW errors delta and check for peak
                var hwErrorsDelta = gpuResponse.Gpu[0].HardwareErrors - hwErrorsTally;
                hwErrorsTally = gpuResponse.Gpu[0].HardwareErrors;
                if (hwErrorsDelta > peakHwErrors)
                {
                    peakHwErrors = hwErrorsDelta;
                }

                // Log to csv file
                AppendToLog(DateTime.Now, gpuResponse.Gpu[0].MemoryClock, gpuClock, currentHashRate, hwErrorsDelta);

                // Save data points for graph
                _hashRatePoints.Add(gpuClock, currentHashRate);
                _hwErrorPoints.Add(gpuClock, hwErrorsDelta);
            }

            CH.Write(string.Format(" - Measurements completed. Resetting GPU engine clock to {0}... ", _saveGpuClock), ConsoleColor.White);
            statusResponse = Send <StatusResponse>(JsonConvert.SerializeObject(new Request {
                Command = "gpuengine", Parameter = _gpuId + "," + _saveGpuClock
            }));
            if (statusResponse.Status[0].Status == "E" || statusResponse.Status[0].Status == "F")
            {
                CH.Exit("Failure", statusResponse.Status[0].Msg);
            }
            CH.Write("Success" + Environment.NewLine, ConsoleColor.Green);

            CH.Write(Environment.NewLine + string.Format("Peak of {0} khash/s detected at GPU clock {1} MHz. See {2} for details.", peakHashRate.ToString("F1"), peakGpuClock, _logFilename) + Environment.NewLine, ConsoleColor.White);

            GenerateGraph();
        }