public override async Task <(double speed, bool ok, string msg)> StartBenchmark(CancellationToken stop, BenchmarkPerformanceType benchmarkType = BenchmarkPerformanceType.Standard)
        {
            // determine benchmark time
            // settup times
            var benchmarkTime = 20; // in seconds

            switch (benchmarkType)
            {
            case BenchmarkPerformanceType.Quick:
                benchmarkTime = 20;
                break;

            case BenchmarkPerformanceType.Standard:
                benchmarkTime = 60;
                break;

            case BenchmarkPerformanceType.Precise:
                benchmarkTime = 120;
                break;
            }

            var algo = AlgorithmName(_algorithmType);

            var commandLine = $"--algo={algo} --benchmark --time-limit {benchmarkTime} --devices {_devices} {_extraLaunchParameters}";

            var(binPath, binCwd) = GetBinAndCwdPaths();
            var bp = new BenchmarkProcess(binPath, binCwd, commandLine);


            var errorList = new List <string> {
                "Unknown algo parameter", "Cuda error", "Non-existant CUDA device"
            };
            var errorFound = false;
            var errorMsg   = "";

            // TODO implement fallback average, final benchmark
            bp.CheckData = (string data) => {
                // check if error
                foreach (var err in errorList)
                {
                    if (data.Contains(err))
                    {
                        bp.TryExit();
                        errorFound = true;
                        errorMsg   = data;
                        return(0, false);
                    }
                }

                return(MinerToolkit.TryGetHashrateAfter(data, "Benchmark:")); // TODO add option to read totals
            };

            var benchmarkTimeout = TimeSpan.FromSeconds(benchmarkTime + 5);
            var benchmarkWait    = TimeSpan.FromMilliseconds(500);
            var t = MinerToolkit.WaitBenchmarkResult(bp, benchmarkTimeout, benchmarkWait, stop);

            var(speed, ok, msg) = await t;
            if (errorFound)
            {
                return(0, false, errorMsg);
            }
            return(speed, ok, msg);
        }
        public override async Task <BenchmarkResult> StartBenchmark(CancellationToken stop, BenchmarkPerformanceType benchmarkType = BenchmarkPerformanceType.Standard)
        {
            // determine benchmark time
            // settup times
            var benchmarkTime = MinerBenchmarkTimeSettings.ParseBenchmarkTime(new List <int> {
                20, 60, 120
            }, MinerBenchmarkTimeSettings, _miningPairs, benchmarkType);                                                                                               // in seconds

            var algo        = AlgorithmName(_algorithmType);
            var timeLimit   = _noTimeLimitOption ? "" : $"--time-limit {benchmarkTime}";
            var commandLine = $"--algo={algo} --benchmark {timeLimit} --devices {_devices} {_extraLaunchParameters}";

            var binPathBinCwdPair = GetBinAndCwdPaths();
            var binPath           = binPathBinCwdPair.Item1;
            var binCwd            = binPathBinCwdPair.Item2;

            Logger.Info(_logGroup, $"Benchmarking started with command: {commandLine}");
            var bp = new BenchmarkProcess(binPath, binCwd, commandLine);


            var errorList = new List <string> {
                "Unknown algo parameter", "Cuda error", "Non-existant CUDA device"
            };
            var errorFound = false;
            var errorMsg   = "";

            var benchHashes     = 0d;
            var benchIters      = 0;
            var benchHashResult = 0d;  // Not too sure what this is..
            // TODO fix this tick based system
            var targetBenchIters = Math.Max(1, (int)Math.Floor(benchmarkTime / 20d));

            // TODO implement fallback average, final benchmark
            bp.CheckData = (string data) => {
                // check if error
                foreach (var err in errorList)
                {
                    if (data.Contains(err))
                    {
                        bp.TryExit();
                        errorFound = true;
                        errorMsg   = data;
                        return(new BenchmarkResult {
                            Success = false, ErrorMessage = errorMsg
                        });
                    }
                }

                //return MinerToolkit.TryGetHashrateAfter(data, "Benchmark:"); // TODO add option to read totals
                var hashrateFinalFoundPair = MinerToolkit.TryGetHashrateAfter(data, "Benchmark:"); // TODO add option to read totals
                var hashrateFinal          = hashrateFinalFoundPair.Item1;
                var finalFound             = hashrateFinalFoundPair.Item2;

                if (finalFound)
                {
                    return(new BenchmarkResult
                    {
                        AlgorithmTypeSpeeds = new List <AlgorithmTypeSpeedPair> {
                            new AlgorithmTypeSpeedPair(_algorithmType, benchHashResult)
                        },
                        Success = true
                    });
                }
                // no final calculate avg speed
                var hashrateTotalFoundPair = MinerToolkit.TryGetHashrateAfter(data, "Total:"); // TODO add option to read totals
                var hashrateTotal          = hashrateTotalFoundPair.Item1;
                var totalFound             = hashrateTotalFoundPair.Item2;
                if (totalFound)
                {
                    benchHashes += hashrateTotal;
                    benchIters++;
                    benchHashResult = (benchHashes / benchIters); // * (1 - DevFee * 0.01);
                }

                return(new BenchmarkResult
                {
                    AlgorithmTypeSpeeds = new List <AlgorithmTypeSpeedPair> {
                        new AlgorithmTypeSpeedPair(_algorithmType, benchHashResult)
                    },
                    Success = benchIters >= targetBenchIters
                });
            };

            var benchmarkTimeout = TimeSpan.FromSeconds(benchmarkTime + 5);
            var benchmarkWait    = TimeSpan.FromMilliseconds(500);
            var t = MinerToolkit.WaitBenchmarkResult(bp, benchmarkTimeout, benchmarkWait, stop);

            return(await t);
        }