0

I was stuck in the limitations of the Boinc Manager interface regarding CPU usage over time. This is particularly important when client runs on a machine that is also used for some other activities and you want to minimize the impact of having Boinc running its processes.

Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164

1 Answers1

0

Besides configuring Manager to run only if computer is not used, when CPU usage is below some threshold, you can also customize it to use only some cores and only in some periods of time.

In order to achieve this, the steps are:

1) locate manager directory - this contains various executable files (like boinccmd.exe), configuration files etc.

2) edit (create if not exists) global_prefs_override.xml configuration file in the manager directory. This should contain at least the tags you want to dynamically change. In my example, 100

3) use a custom made application to change global_prefs_override.xml and inform the manager that it has changed

For my own case, I have created a simple C# Console application that automatically changes cores usage based on provided parameters.

The code is provided below:

namespace BoincCustomizer
{
    class Program
    {
        public const String CustomFileName = "global_prefs_override.xml";
        public const String CoresUsedTag = "max_ncpus_pct";
        public const int DummyYear = 1;

        // this are some fixed public holidays 
        public static IList<DateTime> PublicHolidays = new List<DateTime>()
        {
            new DateTime(DummyYear, 1, 1),
            new DateTime(DummyYear, 1, 2),
            new DateTime(DummyYear, 1, 24),
            new DateTime(DummyYear, 5, 1),
            new DateTime(DummyYear, 8, 15),
            new DateTime(DummyYear, 11, 30),
            new DateTime(DummyYear, 12, 1),
            new DateTime(DummyYear, 12, 25),
            new DateTime(DummyYear, 12, 26)
        };

        public static DateTime GetTodayDate()
        {
            return new DateTime(2015, 12, 1); // DateTime.Now.Date;
        }

        public static bool IsFreeDay(DateTime date)
        {
            if (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday)
                return true;

            DateTime checkDate = new DateTime(DummyYear, date.Month, date.Day);
            if (PublicHolidays.Contains(checkDate))
                return true;

            return false;
        }

        /// <summary>
        /// rewrites custom BOINC xml file based on provided parameters
        /// </summary>
        /// <param name="args"></param>
        public static void Main(string[] args)
        {
            // Parameters:
            // 1 - dayStartHour
            // 2 - nightStartHour
            // 3 - dayCpusPerc
            // 4 - nightCpusPerc
            // 5 - freeDayCpusPerc
            if (args.Length != 5)
            {
                Console.WriteLine("Please specify the following parameters: dayStartHour, nightStartHour, dayCpusPerc, nightCpusPerc, freeDayCpuPerc");
                Console.ReadLine();
                return;
            }

            int dayStartHour = Int32.Parse(args[0]);
            int nightStartHour = Int32.Parse(args[1]);
            int dayCpusPerc = Int32.Parse(args[2]);
            int nightCpusPerc = Int32.Parse(args[3]);
            int freeDayCpusPerc = Int32.Parse(args[4]);

            int cpuPerc = 0;
            if (IsFreeDay(GetTodayDate()))
                cpuPerc = freeDayCpusPerc;
            else
            {
                int currHour = DateTime.Now.Hour;
                bool isDay = currHour >= dayStartHour && currHour < nightStartHour;
                cpuPerc = isDay ? dayCpusPerc : nightCpusPerc;
            }

            String workingDirectory = System.IO.Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
            String overrideFilePath = Path.Combine(workingDirectory, CustomFileName);

            String allText = File.ReadAllText(overrideFilePath);
            String startTag = String.Format("<{0}>", CoresUsedTag);
            String stopTag = String.Format("</{0}>", CoresUsedTag);
            int startIndex = allText.IndexOf(startTag);
            int stopIndex = allText.IndexOf(stopTag);
            if (startIndex < 0 || stopIndex < 0)
            {
                Console.WriteLine("Could not find cpu usage token ");
                return;
            }

            String existingText = allText.Substring(startIndex, stopIndex - startIndex);
            String replacementText = String.Format("{0}{1}", startTag, cpuPerc);
            String replacedText = allText.Replace(existingText, replacementText);
            File.WriteAllText(overrideFilePath, replacedText);

            var startInfo = new ProcessStartInfo();
            startInfo.FileName = @"boinccmd.exe";
            startInfo.Arguments = @"--read_global_prefs_override";
            Process.Start(startInfo);
        }
    }
}

This is rudimentary, but it should be a good start for customizing how the manager runs its processes.

Alexei - check Codidact
  • 22,016
  • 16
  • 145
  • 164