Using dtrace on Solaris, I am able to accumulate on-cpu time for a given process (or execname) for the interval from start until control-C with the following script:
!/usr/sbin/dtrace -qs
dtrace:::BEGIN {
total = 0;
}
sched:::on-cpu
/execname == $$1/
{
self->start = vtimestamp;
}
sched:::off-cpu
/self->start/
{
this->time = vtimestamp - self->start;
total += this->time;
self->start = 0;
}
dtrace:::END {
printf("Total Time on CPU: %d us\n",total/1000);
}
(Accumulated time has a fine-grain granularity allowing nano/microsecond accumulation.)
Over the same timeframe, I would like to accumulate all or many processes in an array and report on all accumulated cpu time at break (^C).
What is the best way to do this?
Okay, with a bit more work I've solved my problem.
Here is the way to get microseconds for all processes (but display per process) over the interval.
#!/usr/sbin/dtrace -qs
dtrace:::BEGIN {
total = 0;
starttimestamp=timestamp;
printf("Starting...\n");
}
sched:::on-cpu
/pid!=0/
{
self->start = vtimestamp;
}
sched:::off-cpu
/self->start && pid!=0/
{
this->time = vtimestamp - self->start;
total += this->time;
#proctime[pid,uid,execname,curpsinfo->pr_psargs] = sum( this->time/1000 );
self->start = 0;
}
dtrace:::END {
printf("Elapsed time %d usec\n",(timestamp-starttimestamp)/1000);
printf("Total Time on CPU: %d us\n",total/1000);
printa(#proctime);
}
Related
Could anyone explain me the time complexity of this method?
int sqrt = (int) Math.sqrt(n) + 1;
for (int i = 2; i < sqrt; i++) {
if (n % i == 0) {
return false;
}
}
return true;
I'm not really good in this subject and tried to find out some info online but could't find any explanation.
its On(1) - linear, as it its linearly proportional on i (or less due to early stopping from module check); this is typical for a one level for loop
I have a question on this code.
It's the code for finding delay.
in order to estimate the delay,
in my mind,I should find the largest value from the array mean_bit_counts[], but in the picture, they choose the smallest one. So could you solve my problem? Thanks!
// Find |candidate_delay|, |value_best_candidate| and |value_worst_candidate|
// of |mean_bit_counts|.
for (i = 0; i < self->history_size; i++) {
if (self->mean_bit_counts[i] < value_best_candidate) {
value_best_candidate = self->mean_bit_counts[I];
candidate_delay = I;
}
if (self->mean_bit_counts[i] > value_worst_candidate) {
value_worst_candidate = self->mean_bit_counts[I];
}
}
valley_depth = value_worst_candidate - value_best_candidate;
How could I generate steady CPU load in C#, lower than 100% for a certain time? I would also like to be able to change the load amount after a certain period of time. How do you recommend to generate usage spikes for a very short time?
First off, you have to understand that CPU usage is always an average over a certain time. At any given time, the CPU is either working or it is not. The CPU is never 40% working.
We can, however, simulate a 40% load over say a second by having the CPU work for 0.4 seconds and sleep 0.6 seconds. That gives an average utilization of 40% over that second.
Cutting it down to smaller than one second, say 100 millisecond chunks should give even more stable utilization.
The following method will take an argument that is desired utilization and then utilize a single CPU/core to that degree:
public static void ConsumeCPU(int percentage)
{
if (percentage < 0 || percentage > 100)
throw new ArgumentException("percentage");
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
// Make the loop go on for "percentage" milliseconds then sleep the
// remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms
if (watch.ElapsedMilliseconds > percentage)
{
Thread.Sleep(100 - percentage);
watch.Reset();
watch.Start();
}
}
}
I'm using a stopwatch here because it is more accurate than the the TickCount property, but you could likewise use that and use subtraction to check if you've run long enough.
Two things to keep in mind:
on multi core systems, you will have to spawn one thread for each core. Otherwise, you'll see only one CPU/core being exercised giving roughly "percentage/number-of-cores" utilization.
Thread.Sleep is not very accurate. It will never guarantee times exactly to the millisecond so you will see some variations in your results
To answer your second question, about changing the utilization after a certain time, I suggest you run this method on one or more threads (depending on number of cores) and then when you want to change utilization you just stop those threads and spawn new ones with the new percentage values. That way, you don't have to implement thread communication to change percentage of a running thread.
Just in add of the Isak response, I let here a simple implementation for multicore:
public static void CPUKill(object cpuUsage)
{
Parallel.For(0, 1, new Action<int>((int i) =>
{
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
if (watch.ElapsedMilliseconds > (int)cpuUsage)
{
Thread.Sleep(100 - (int)cpuUsage);
watch.Reset();
watch.Start();
}
}
}));
}
static void Main(string[] args)
{
int cpuUsage = 50;
int time = 10000;
List<Thread> threads = new List<Thread>();
for (int i = 0; i < Environment.ProcessorCount; i++)
{
Thread t = new Thread(new ParameterizedThreadStart(CPUKill));
t.Start(cpuUsage);
threads.Add(t);
}
Thread.Sleep(time);
foreach (var t in threads)
{
t.Abort();
}
}
For a uniform stressing: Isak Savo's answer with a slight tweak. The problem is interesting. In reality there are workloads that far exceed it in terms of wattage used, thermal output, lane saturation, etc. and perhaps the use of a loop as the workload is poor and almost unrealistic.
int percentage = 80;
for (int i = 0; i < Environment.ProcessorCount; i++)
{
(new Thread(() =>
{
Stopwatch watch = new Stopwatch();
watch.Start();
while (true)
{
// Make the loop go on for "percentage" milliseconds then sleep the
// remaining percentage milliseconds. So 40% utilization means work 40ms and sleep 60ms
if (watch.ElapsedMilliseconds > percentage)
{
Thread.Sleep(100 - percentage);
watch.Reset();
watch.Start();
}
}
})).Start();
}
Each time you have to set cpuUsageIncreaseby variable.
for example:
1- Cpu % increase by > cpuUsageIncreaseby % for one minute.
2- Go down to 0% for 20 seconds.
3- Goto step 1.
private void test()
{
int cpuUsageIncreaseby = 10;
while (true)
{
for (int i = 0; i < 4; i++)
{
//Console.WriteLine("am running ");
//DateTime start = DateTime.Now;
int cpuUsage = cpuUsageIncreaseby;
int time = 60000; // duration for cpu must increase for process...
List<Thread> threads = new List<Thread>();
for (int j = 0; j < Environment.ProcessorCount; j++)
{
Thread t = new Thread(new ParameterizedThreadStart(CPUKill));
t.Start(cpuUsage);
threads.Add(t);
}
Thread.Sleep(time);
foreach (var t in threads)
{
t.Abort();
}
//DateTime end = DateTime.Now;
//TimeSpan span = end.Subtract(start);
//Console.WriteLine("Time Difference (seconds): " + span.Seconds);
//Console.WriteLine("10 sec wait... for another.");
cpuUsageIncreaseby = cpuUsageIncreaseby + 10;
System.Threading.Thread.Sleep(20000);
}
}
}
Let's say we have an algorithm that goes through a list of n numbers twice and counts the number of the ones above 50 in one run and the ones below 50 in the other run and stores these in two variables.
If we change it to do the same in one run by incrementing not just one but either of the variables in each step, do we change time complexity of the algorithm? Do we consider the new one faster?
I know it will require less steps but not exactly sure about time complexity notation.
EDIT:
Pseudocode 1:
for (i = 0; i < TOTAL_NUMBERS; i++) {
if (numbers[i] >= 50) {
greaterThan50++;
}
}
for (i = 0; i < TOTAL_NUMBERS; i++) {
if (numbers[i] < 50) {
lessThan50++;
}
}
Pseudocode 2:
for (i = 0; i < TOTAL_NUMBERS; i++) {
if (numbers[i] >= 50) {
greaterThan50++;
}
else {
lessThan50++;
}
}
Something is simple if you can obtain the same result but with smallest expression posible. So in this case if you combine the update of the two counters in the same loop the algorithm will need less CPU cycles to be executed. You can also save time in the number validation cause you can just make one if / else statement to do what you need.
A pseudocode could look like this:
for (i = 0; i < TOTAL_NUMBERS; i++) {
if (numbers[i] >= 50) {
greaterThan50 ++;
}
else {
lessThan50 ++;
}
}
If you want to exclude the numbers that are equal 50 you can do something like:
for (int i = 0; i < TOTAL_NUMBERS; i++) {
if (numbers[i] > 50) {
greaterThan50 ++;
}
else if (numbers[i] < 50) {
lessThan50 ++;
}
}
As you might notice in this last example you are doing an extra validation so it will take an extra step, but this algorithm will still be much faster than looping through the list twice (and also simpler since it requires less lines of code and makes the code more readable and easy to understand).
I hope this helps with your question :)
Big O notation is a general statement for how a measurement (execution time in your case) changes as input grows. The first takes twice as long to execute, but both versions execution times grow linearly with regard to input size, so they're both O(n) algorithms.
more reading here: http://en.wikipedia.org/wiki/Big_O_notation
#using <mscorlib.dll>
#using <System.dll>
using namespace System;
using namespace System::Text;
using namespace System::IO;
using namespace System::Net;
using namespace System::Net::Sockets;
using namespace System::Collections;
Errors: IntelliSense: "#using" requires C++/CLI to be enabled....
how to fix this prob!?
Your project settings are wrong. Specifically Configuration Properties, General, Common Language Runtime support.
Fall in the pit of success by starting your project by picking one of the project templates in the CLR node.
Choose Project -> Properties from the menu bar. In the Project properties window, under Configuration Properties -> General, make sure that Common Language Runtime Support is set to Common Language Runtime Support (/clr)
In VS2019 it the steps would be :
1/ Right click on the project
2/ Project
3/ Properties
4/ Configuration Properties
5/ Advanced
6/ Common Language Runtime Support change it to Common Language Runtime Support(/clr)
Enable it in your project settings (right click on the projet -> settings) the first tab should provide the option.
The MSDN has a nice example for testing the difference in performance, Parse vs tryParse:
Stopwatch Example
#include <stdio.h>
#using <System.dll>
using namespace System;
using namespace System::Diagnostics;
void DisplayTimerProperties()
{
// Display the timer frequency and resolution.
if (Stopwatch::IsHighResolution)
{
Console::WriteLine("Operations timed using the system's high-resolution performance counter.");
}
else
{
Console::WriteLine("Operations timed using the DateTime class.");
}
Int64 frequency = Stopwatch::Frequency;
Console::WriteLine(" Timer frequency in ticks per second = {0}", frequency);
Int64 nanosecPerTick = (1000L * 1000L * 1000L) / frequency;
Console::WriteLine(" Timer is accurate within {0} nanoseconds", nanosecPerTick);
}
void TimeOperations()
{
Int64 nanosecPerTick = (1000L * 1000L * 1000L) / Stopwatch::Frequency;
const long numIterations = 10000;
// Define the operation title names.
array<String^>^operationNames = { "Operation: Int32.Parse(\"0\")","Operation: Int32.TryParse(\"0\")","Operation: Int32.Parse(\"a\")","Operation: Int32.TryParse(\"a\")" };
// Time four different implementations for parsing
// an integer from a string.
for (int operation = 0; operation <= 3; operation++)
{
// Define variables for operation statistics.
Int64 numTicks = 0;
Int64 numRollovers = 0;
Int64 maxTicks = 0;
Int64 minTicks = Int64::MaxValue;
int indexFastest = -1;
int indexSlowest = -1;
Int64 milliSec = 0;
Stopwatch ^ time10kOperations = Stopwatch::StartNew();
// Run the current operation 10001 times.
// The first execution time will be tossed
// out, since it can skew the average time.
for (int i = 0; i <= numIterations; i++)
{
Int64 ticksThisTime = 0;
int inputNum;
Stopwatch ^ timePerParse;
switch (operation)
{
case 0:
// Parse a valid integer using
// a try-catch statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch::StartNew();
try
{
inputNum = Int32::Parse("0");
}
catch (FormatException^)
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse->Stop();
ticksThisTime = timePerParse->ElapsedTicks;
break;
case 1:
// Parse a valid integer using
// the TryParse statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch::StartNew();
if (!Int32::TryParse("0", inputNum))
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse->Stop();
ticksThisTime = timePerParse->ElapsedTicks;
break;
case 2:
// Parse an invalid value using
// a try-catch statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch::StartNew();
try
{
inputNum = Int32::Parse("a");
}
catch (FormatException^)
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse->Stop();
ticksThisTime = timePerParse->ElapsedTicks;
break;
case 3:
// Parse an invalid value using
// the TryParse statement.
// Start a new stopwatch timer.
timePerParse = Stopwatch::StartNew();
if (!Int32::TryParse("a", inputNum))
{
inputNum = 0;
}
// Stop the timer, and save the
// elapsed ticks for the operation.
timePerParse->Stop();
ticksThisTime = timePerParse->ElapsedTicks;
break;
default:
break;
}
// Skip over the time for the first operation,
// just in case it caused a one-time
// performance hit.
if (i == 0)
{
time10kOperations->Reset();
time10kOperations->Start();
}
else
{
// Update operation statistics
// for iterations 1-10001.
if (maxTicks < ticksThisTime)
{
indexSlowest = i;
maxTicks = ticksThisTime;
}
if (minTicks > ticksThisTime)
{
indexFastest = i;
minTicks = ticksThisTime;
}
numTicks += ticksThisTime;
if (numTicks < ticksThisTime)
{
// Keep track of rollovers.
numRollovers++;
}
}
}
// Display the statistics for 10000 iterations.
time10kOperations->Stop();
milliSec = time10kOperations->ElapsedMilliseconds;
Console::WriteLine();
Console::WriteLine("{0} Summary:", operationNames[operation]);
Console::WriteLine(" Slowest time: #{0}/{1} = {2} ticks", indexSlowest, numIterations, maxTicks);
Console::WriteLine(" Fastest time: #{0}/{1} = {2} ticks", indexFastest, numIterations, minTicks);
Console::WriteLine(" Average time: {0} ticks = {1} nanoseconds", numTicks / numIterations, (numTicks * nanosecPerTick) / numIterations);
Console::WriteLine(" Total time looping through {0} operations: {1} milliseconds", numIterations, milliSec);
}
}
int main()
{
DisplayTimerProperties();
Console::WriteLine();
Console::WriteLine("Press the Enter key to begin:");
Console::ReadLine();
Console::WriteLine();
TimeOperations();
getchar();
}
//Operations timed using the system's high-resolution performance counter.
//Timer frequency in ticks per second = 3319338
//Timer is accurate within 301 nanoseconds
//
//Press the Enter key to begin :
//
//
//
//Operation : Int32.Parse("0") Summary :
// Slowest time : #4483 / 10000 = 95 ticks
// Fastest time : #3 / 10000 = 0 ticks
// Average time : 0 ticks = 99 nanoseconds
// Total time looping through 10000 operations : 1 milliseconds
//
// Operation : Int32.TryParse("0") Summary :
// Slowest time : #7720 / 10000 = 187 ticks
// Fastest time : #1 / 10000 = 0 ticks
// Average time : 0 ticks = 109 nanoseconds
// Total time looping through 10000 operations : 1 milliseconds
//
// Operation : Int32.Parse("a") Summary :
// Slowest time : #3701 / 10000 = 2388 ticks
// Fastest time : #2698 / 10000 = 102 ticks
// Average time : 116 ticks = 35109 nanoseconds
// Total time looping through 10000 operations : 352 milliseconds
//
// Operation : Int32.TryParse("a") Summary :
// Slowest time : #8593 / 10000 = 23 ticks
// Fastest time : #1 / 10000 = 0 ticks
// Average time : 0 ticks = 88 nanoseconds
// Total time looping through 10000 operations : 1 milliseconds
If you are using Visual Studio, you might have to do some installations pre-hand. To install those, open the Visual Studio Installer from the Windows Start menu. Make sure that the Desktop development with C++ tile is checked, and in the Optional components section, also check C++/CLI Support.