The existing question suggests CurrentClockSpeed, but in my system, it just returns the same value as MaxClockSpeed. The code below prints out the same two values over and over again.
Task.Run(() =>
{
ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'");
while (true)
{
Debug.WriteLine("Max=" + Mo["MaxClockSpeed"] + ", Current=" + Mo["CurrentClockSpeed"]);
System.Threading.Thread.Sleep(1000);
}
Mo.Dispose(); //return and such later in the code
});
But all other applications like Task Manager, CPU-Z, Hardware Info, etc, show variable clock speed. That is, if I run a process that uses 100% of the CPU, the speed goes up, and if I terminate that process, it goes down. How can I get THAT value?
I mean, for example, the value in the "Speed" section of the screenshot I found in Google Search. Not the "Maximum speed" value that never changes.
If you mean CPU current usage processes
use this function in seperate thread :
private void get_cpuUsage()
{
try
{
string processname = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
var perfCounter = new PerformanceCounter("Process", "% Processor Time", processname);
int coreCount = 0;
foreach (var item in new System.Management.ManagementObjectSearcher("Select * from Win32_Processor").Get())
{
coreCount += int.Parse(item["NumberOfCores"].ToString());
}
while (true)
{
Thread.Sleep(500);
double perfVal = perfCounter.NextValue() / Environment.ProcessorCount;
int cpu = (int)Math.Round(perfVal, 0);// /
double cpuvalue = Math.Round(perfVal, 1);
Invoke((MethodInvoker)delegate
{
cpu_bar.Text = cpuvalue.ToString(); // diaplay current % processes
});
}
}
catch(Exception ex)
{
messagebox.show(ex.message);
}
}
Related
How can I get in c# the CPU frequency (example : 2Ghz) ?
It's simple but I don't find it in the environnement variables.
Thanks :)
var searcher = new ManagementObjectSearcher(
"select MaxClockSpeed from Win32_Processor");
foreach (var item in searcher.Get())
{
var clockSpeed = (uint)item["MaxClockSpeed"];
}
if you wish to get other fields look at class Win32_processor
Try this code
using System.Management;
uint currentsp , Maxsp;
public void CPUSpeed()
{
using(ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'"))
{
currentsp = (uint)(Mo["CurrentClockSpeed"]);
Maxsp = (uint)(Mo["MaxClockSpeed"]);
}
}
If you want to get the turbo speed, you can make use of the "% Processor Performance" performance counter and multiply it with the WMI "MaxClockSpeed" as follows:
private string GetCPUInfo()
{
PerformanceCounter cpuCounter = new PerformanceCounter("Processor Information", "% Processor Performance", "_Total");
double cpuValue = cpuCounter.NextValue();
Thread loop = new Thread(() => InfiniteLoop());
loop.Start();
Thread.Sleep(1000);
cpuValue = cpuCounter.NextValue();
loop.Abort();
foreach (ManagementObject obj in new ManagementObjectSearcher("SELECT *, Name FROM Win32_Processor").Get())
{
double maxSpeed = Convert.ToDouble(obj["MaxClockSpeed"]) / 1000;
double turboSpeed = maxSpeed * cpuValue / 100;
return string.Format("{0} Running at {1:0.00}Ghz, Turbo Speed: {2:0.00}Ghz", obj["Name"], maxSpeed, turboSpeed);
}
return string.Empty;
}
The InfiniteLoop method is simply an integer that gets 1 added and subtracted:
private void InfiniteLoop()
{
int i = 0;
while (true)
i = i + 1 - 1;
}
The InfiniteLoop method is just added to give the CPU something to do and turbo in the process. The loop is allowed to run for a second before the next value is taken and the loop aborted.
One could take the information out of the registry, but dunno if it works on Windows XP or older (mine is Windows 7).
HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/CentralProcessor/0/ProcessorName
reads like
Intel(R) Core(TM)2 Quad CPU Q6600 # 2.40GHz
for me.
Something like this code could retrieve the information (not tested):
RegistryKey processor_name = Registry.LocalMachine.OpenSubKey(#"Hardware\Description\System\CentralProcessor\0", RegistryKeyPermissionCheck.ReadSubTree);
if (processor_name != null)
{
if (processor_name.GetValue("ProcessorNameString") != null)
{
string value = processor_name.GetValue("ProcessorNameString");
string freq = value.Split('#')[1];
...
}
}
(source: here)
You can get it via WMI, but it's quite slow so if you're going to be getting it on more than one occasion I'd suggest you cache it - something like:
namespace Helpers
{
using System.Management;
public static class HardwareHelpers
{
private static uint? maxCpuSpeed = null;
public static uint MaxCpuSpeed
{
get
{
return maxCpuSpeed.HasValue ? maxCpuSpeed.Value : (maxCpuSpeed = GetMaxCpuSpeed()).Value;
}
}
private static uint GetMaxCpuSpeed()
{
using (var managementObject = new ManagementObject("Win32_Processor.DeviceID='CPU0'"))
{
var sp = (uint)(managementObject["MaxClockSpeed"]);
return sp;
}
}
}
}
This is a weird one, I have a Thread[] of worker threads which each process items in a ConcurrentQueue<string> until the queue is empty, at which point the rest of the program continues.
This works until about ~1500 items at which point all threads stay blocked in the WaitSleepJoin state and never process any of the items in the queue.
I've tried stepping through my code and it appears that the threads are still created, still started and are alive but get blocked immediately and never run their relevant function.
I'm completely flummoxed so any help would be appreciated!
The relevant sections of code are below:
Main Thread Segment:
ConcurrentQueue<string> convertionQueue = new ConcurrentQueue<string>();
List<Thread> converterThreads = new List<Thread>();
Directory.GetFiles(_folderOne, "*.fdf", SearchOption.AllDirectories).ToList().ForEach(file => convertionQueue.Enqueue(file));
Directory.GetFiles(_folderTwo, "*.fdf", SearchOption.AllDirectories).ToList().ForEach(file => convertionQueue.Enqueue(file));
int filesDone = 0;
int totalFiles = convertionQueue.Count;
progressBar.Maximum = totalFiles;
panel1.Visible = true;
for (int i = 0; i < Environment.ProcessorCount; i++)
{
converterThreads.Add(new Thread(() => ConvThreadWorker(convertionQueue, ref filesDone)));
}
converterThreads.ForEach(thread => thread.Start());
DateTime lastTick = DateTime.Now;
int lastFilesDone = 0;
int[] valuesSpeed = { 1, 1, 1, 1, 1 };
int[] valuesTime = { 1, 1, 1, 1, 1 };
int counter = 0;
while (converterThreads.Any(thread => thread.IsAlive))
{
TimeSpan t = DateTime.Now - lastTick;
int deltaFiles = filesDone - lastFilesDone;
double speed = (float)t.TotalMilliseconds <= 0.0 ? 0.0 : deltaFiles / (float)t.TotalMilliseconds;
double tMinus = speed <= 0 ? 0.0 : (totalFiles - filesDone) / speed;
int currentSpeed = (int)(speed * 1000);
int currentTime = (int)(tMinus / 1000);
valuesSpeed[counter] = currentSpeed;
valuesTime[counter] = currentTime;
lblFilesLeft.Text = string.Format("{0}/{1}", filesDone, totalFiles);
lblSpeed.Text = valuesSpeed.Sum() / 5 + " /s";
lblTime.Text = valuesTime.Sum() / 5 + " s";
lblFilesLeft.Update();
lblSpeed.Update();
lblTime.Update();
progressBar.Value = filesDone;
progressBar.Update();
lastTick = DateTime.Now;
lastFilesDone = filesDone;
counter = ++counter % 5;
Thread.Sleep(500);
}
Worker Function:
private void ConvThreadWorker(ConcurrentQueue<string> queue, ref int fileCounter)
{
while (!queue.IsEmpty)
{
string file;
if (queue.TryDequeue(out file))
{
ConvToG(file);
fileCounter++;
}
}
}
Convertion Function:
private void ConvToG(string file)
{
MessageBox.Show("Entering Convertion Function");
if (!_fileCreationDictionary.ContainsKey(file))
{
DateTime lastTimeModified = File.GetLastWriteTime(file);
_fileCreationDictionary.AddOrUpdate(file, lastTimeModified, (key,oldvalue)=>lastTimeModified);
}
ProcessStartInfo procStart = new ProcessStartInfo
{
Arguments = file,
UseShellExecute = true,
FileName = Fdfg,
WindowStyle = ProcessWindowStyle.Hidden
};
Process process = new Process {StartInfo = procStart};
MessageBox.Show("Starting convertion process");
process.Start();
process.WaitForExit();
MessageBox.Show("Finished");
}
The confusing part appears to be how this all revolves around the number of items in the queue, yet there appears to be no overflow.
UPDATE: Adding the mbox's shows that it freezes on the process.Start() section of code, with no errors and will not proceed past that point.
UPDATE 2: If UseShellExecute = false the code works. Which is very confusing to say the least.
I have done something similar with threads spawning processes to collate data. I had issues around the actual process starting and hanging. What I did to get my program working was something like this:
using (Process process = Process.Start(startInfo)) {
if(process.WaitForExit(timeOutMilliseconds)) {
MessageBox.Show("Process exited ok");
//...snip
} else {
MessageBox.Show("Process did not exit in time!");
//...snip
process.Kill();
}
}
There is a bit more going on in the background, regarding limiting the number of running process, etc, but I found that occasionally, for an unknown reason, that I would see several process in the task manager just hanging around forever.
Hope that helps?
I'm making service for watch on some controller data and if it changing then I write it to DB. Seems simple. previosly I realized the same with Delphi, but now I am on C# (.Net 4.5). Now service works good with 100 tasks, but eats about 7-8% of CPU time. My Delphi service eats about 0%.
How can I reduce time which service eat from CPU?
P.S.: each task has own nstance of class to connect and insert into DB and work with local copy of data.
int TagCnt = DataCtrl.TagList.Count;
stopExec = false;
if (TagCnt != 0)
{
tasks = new Task[TagCnt];
for (int i = 0; i <= TagCnt - 1; i++)
{
int TempID = i;
tasks[TempID] = Task.Run(async () => // make threads for parallel read-write tasks // async
{
Random rand = new Random();
TimeSpan delay = TimeSpan.FromMilliseconds(rand.Next(1000, 1500))
try
{
while (!stopExec)
{
cToken.ThrowIfCancellationRequested();
//do basic job here
await Task.Delay(delay, cToken);
}//while end
}
catch (...)
{
...
}
}, cToken);
}
Recently I've been facing a similar conundrum and managed to solve the erratic CPU usage by using a set of dedicated long-running tasks to carry out the asynchronous work in my app like so:
Dim NumThreads As Integer = 10
Dim CanTokSrc As New CancellationTokenSource
Dim LongRunningTasks As Task() = New Task(NumThreads) {}
Dim i As Integer
Do Until i = LongRunningTasks.Count
LongRunningTasks(i) = Task.Factory.StartNew(Sub()
Do Until CanTokSrc.IsCancellationRequested
'DO WORK HERE
Loop
End Sub, CanTokSrc.Token, TaskCreationOptions.LongRunning)
i = i + 1
Loop
This image shows the difference it made in CPU usage for the same workload (shown after 9am).
So I think bypassing the thread pool by using dedicated/ long running tasks like above could improve CPU utilization in some cases. It certainly did in mine :-)
I moved to timer instructions because it's a windows service. Every event on timer load is about 7-10% and between is 0%. I tried to apply tasks, ThreadSchedule - they seems more heavy.
private void OnReadTimer(object source, ElapsedEventArgs e) //check states on timer
{
int TagCnt = DataCtrl.TagList.Count;
po.MaxDegreeOfParallelism = DataCtrl.TagList.Count;
// string ss = "tags=" + TagCnt;
//int TempID;
Random rand = new Random();
try
{
if (TagCnt != 0)
{
ParallelLoopResult loopResult = Parallel.For(0, TagCnt - 1, po, (i, loopState) =>
{
po.CancellationToken.ThrowIfCancellationRequested();
int TempID = i;
Thread.Sleep(rand.Next(100, 200));
int ID = 0;
bool State = false;
long WT = 0;
int ParID = 0;
bool Save = false;
ReadStates(TempID, out ID, out State, out WT, out ParID, out Save);
lock (locker)
{
if (Save) WriteState(ID, State, WT, ParID);
}
});
}
}
catch (TaskCanceledException)
{
}
catch (System.NullReferenceException eNullRef)
{
AddLog("Error:" + eNullRef);
}
catch (System.ArgumentOutOfRangeException e0)
{
AddLog("Error:" + e0);
}
catch (Exception e1)
{
//AddLog("Error while processing data: " + e1);
}
}
I moved to basic threads with infinite loops inside. It gets endless threads for my needs. No heavy recreating/restarting and so on. Now it works nice like Delphi service, but more comfortable job with data and DB. I starts threads with this procedure from lambda new thread()=>:
void RWDeviceState(int i)
{
try
{
int TempID = i;
long StartTime;
long NextTime;
long Period = 3000;
int ID = 0;
bool State = false;
long WT = 0;
int ParID = 0;
bool Save = false;
while (ExecutionAllowed)
{
Save = false;
ReadStates(TempID, out ID, out State, out WT, out ParID, out Save);
lock (locker)
{
if (Save) WriteState(ID, State, WT, ParID);
}
StartTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
NextTime = StartTime + Period;
while (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond < NextTime && ExecutionAllowed)
{
Thread.Sleep(40);
}
}
There are two particular techniques that will help reduce CPU usage in long loop waits. One, is to use the threading sleep method. This is good for example in standalone applications, less in windows services.
In a service, for the second, you should be using timers. These fire at regular intervals, so in between the intervals the CPU is not solicited.
I have multiple tasks in an array, that are used to compute prime numbers in a given range. To undergo a comparison of tasks vs thread performance, I want to use threads within tasks and then check the performance stats.
How will the threads be used with tasks, so far this is what I have done:
public Form1()
{
InitializeComponent();
cpuCounter = new PerformanceCounter();
cpuCounter.CategoryName = "Processor";
cpuCounter.CounterName = "% Processor Time";
cpuCounter.InstanceName = "_Total";
ramCounter = new PerformanceCounter("Memory", "Available MBytes");
this.scheduler = TaskScheduler.FromCurrentSynchronizationContext();
this.numericUpDown1.Maximum = int.MaxValue;
}
private void btnCalculate_Click(object sender, EventArgs e)
{
//get the lower and upper bounds for prime range
int lower = int.Parse(this.numericUpDown1.Value.ToString());
int upper = 0 ;
//get the time in milliseconds for task deadline
int taskDeadline = int.Parse(this.time.Text);
//determine tasks completed
int tasksCompleted = 0;
Random random = new Random();
for (int taskCount = 1; taskCount <= 1; ++taskCount)
{
int taskArraySize = taskCount * 100;
Task[] taskArray = new Task[taskArraySize];
this.txtNumOfPrimes.Text += "Performing test for " +
taskArraySize.ToString() +
" tasks" +
Environment.NewLine +
Environment.NewLine;
for (int i = 0; i < taskArray.Length; i++)
{
upper = random.Next(5, 10);
taskArray[i] = new Task(() => getPrimesInRange(lower, upper));
taskArray[i].Start();
bool timeout = taskArray[i].Wait(taskDeadline);
if (!timeout)
{
// If it hasn't finished at timeout display message
this.txtNumOfPrimes.Text +=
"Message to User: Task not completed, Status=> " +
taskArray[i].Status.ToString() +
Environment.NewLine;
}
else
{
this.txtNumOfPrimes.Text += "Task completed in timeout " +
", CPU usage: " + this.getCurrentCpuUsage() +
", RAM usage: " +
this.getAvailableRAM() +
Environment.NewLine;
tasksCompleted++;
}
}
}
this.txtNumOfPrimes.Text += Environment.NewLine;
this.txtNumOfPrimes.Text +=
"Tasks Completed: " +
tasksCompleted.ToString() +
Environment.NewLine;
}
The whole point of tasks is "simplifying the process of adding parallelism and concurrency to applications". Indeed (from http://msdn.microsoft.com/en-us/library/dd537609):
Behind the scenes, tasks are queued to the ThreadPool, which has been
enhanced with algorithms (like hill-climbing) that determine and
adjust to the number of threads that maximizes throughput. This makes
tasks relatively lightweight, and you can create many of them to
enable fine-grained parallelism. To complement this, widely-known
work-stealing algorithms are employed to provide load-balancing.
In short, tasks do the thread work without much of the hassle and legwork.
To compare the two, consider using Parrallel.ForEach for tasks. For example:
public class PrimeRange
{
public int Start;
public int Snd;
}
List<PrimeRange> primes = new []
{
new PrimeRange{Start = 0, End = 1000},
new PrimeRange{Start = 1001, End = 2000}
// An so on
};
Parallel.ForEach(primes, x => CalculatePrimes(x, OnResult())));
where CalculatePrimes is a method that takes a PrimeRange and a delegate to call when the primes have been calculated. Parraler.ForEach will start a task for each element of primes and run CalculatePrimes() on it and handle the thread assignment and scheduling for you.
To compare it to threads, use something like:
List<Thread> threads = new List<Thread>();
foreach(PrimeRange primeRange in primes)
{
threads = new Thread(CalculatePrimes).Start(x);
}
foreach(var thread in threads)
{
thread.Join();
}
where CalculatePrimes would need to also store the results (or something similar). See C# Waiting for multiple threads to finish for more information about waiting on running threads.
You could time the results using a StopWatch.
How can I get in c# the CPU frequency (example : 2Ghz) ?
It's simple but I don't find it in the environnement variables.
Thanks :)
var searcher = new ManagementObjectSearcher(
"select MaxClockSpeed from Win32_Processor");
foreach (var item in searcher.Get())
{
var clockSpeed = (uint)item["MaxClockSpeed"];
}
if you wish to get other fields look at class Win32_processor
Try this code
using System.Management;
uint currentsp , Maxsp;
public void CPUSpeed()
{
using(ManagementObject Mo = new ManagementObject("Win32_Processor.DeviceID='CPU0'"))
{
currentsp = (uint)(Mo["CurrentClockSpeed"]);
Maxsp = (uint)(Mo["MaxClockSpeed"]);
}
}
If you want to get the turbo speed, you can make use of the "% Processor Performance" performance counter and multiply it with the WMI "MaxClockSpeed" as follows:
private string GetCPUInfo()
{
PerformanceCounter cpuCounter = new PerformanceCounter("Processor Information", "% Processor Performance", "_Total");
double cpuValue = cpuCounter.NextValue();
Thread loop = new Thread(() => InfiniteLoop());
loop.Start();
Thread.Sleep(1000);
cpuValue = cpuCounter.NextValue();
loop.Abort();
foreach (ManagementObject obj in new ManagementObjectSearcher("SELECT *, Name FROM Win32_Processor").Get())
{
double maxSpeed = Convert.ToDouble(obj["MaxClockSpeed"]) / 1000;
double turboSpeed = maxSpeed * cpuValue / 100;
return string.Format("{0} Running at {1:0.00}Ghz, Turbo Speed: {2:0.00}Ghz", obj["Name"], maxSpeed, turboSpeed);
}
return string.Empty;
}
The InfiniteLoop method is simply an integer that gets 1 added and subtracted:
private void InfiniteLoop()
{
int i = 0;
while (true)
i = i + 1 - 1;
}
The InfiniteLoop method is just added to give the CPU something to do and turbo in the process. The loop is allowed to run for a second before the next value is taken and the loop aborted.
One could take the information out of the registry, but dunno if it works on Windows XP or older (mine is Windows 7).
HKEY_LOCAL_MACHINE/HARDWARE/DESCRIPTION/CentralProcessor/0/ProcessorName
reads like
Intel(R) Core(TM)2 Quad CPU Q6600 # 2.40GHz
for me.
Something like this code could retrieve the information (not tested):
RegistryKey processor_name = Registry.LocalMachine.OpenSubKey(#"Hardware\Description\System\CentralProcessor\0", RegistryKeyPermissionCheck.ReadSubTree);
if (processor_name != null)
{
if (processor_name.GetValue("ProcessorNameString") != null)
{
string value = processor_name.GetValue("ProcessorNameString");
string freq = value.Split('#')[1];
...
}
}
(source: here)
You can get it via WMI, but it's quite slow so if you're going to be getting it on more than one occasion I'd suggest you cache it - something like:
namespace Helpers
{
using System.Management;
public static class HardwareHelpers
{
private static uint? maxCpuSpeed = null;
public static uint MaxCpuSpeed
{
get
{
return maxCpuSpeed.HasValue ? maxCpuSpeed.Value : (maxCpuSpeed = GetMaxCpuSpeed()).Value;
}
}
private static uint GetMaxCpuSpeed()
{
using (var managementObject = new ManagementObject("Win32_Processor.DeviceID='CPU0'"))
{
var sp = (uint)(managementObject["MaxClockSpeed"]);
return sp;
}
}
}
}