I would like to do some microbenchmarks, and try to do them right. Unfortunately dynamic frequency scaling makes benchmarking highly unreliable.
Is there a way to programmatically (C++, Windows) find out if dynamic frequency scaling is enabled? If, can this be disabled in a program?
Ive tried to just use a warmup phase that uses 100% CPU for a second before the actual benchmark takes place, but this turned out to be not reliable either.
UPDATE: Even when I disable SpeedStep in the BIOS, cpu-z shows that the frequency changes between 1995 and 2826 GHz
In general, you need to do the following steps:
Call CallNtPowerInformation() and pass SystemPowerCapabilities to InformationLevel parameter, set lpInputBuffer and nInputBufferSize to NULL, then set lpOutputBuffer to SYSTEM_POWER_CAPABILITIES structure, and set nOutputBufferSize to the size of the structure. After this first call, SYSTEM_POWER_CAPABILITIES structure containing the current system power capabilities. To check whether the system supports processor throttling, read the value of ProcessorThrottle.
There are other two members we are interested in, they are, ProcessorMinThrottle and ProcessorMaxThrottle; they represents the minimum and maximum level of system processor throttling supported, expressed as a percentage. If both members has already values 100%, this means CPU throttling is currently disabled, so you don't need to reconfigure it.
To disable CPU throttling, you need to set ProcessorMinThrottle and ProcessorMaxThrottle to 100%. To do this, call CallNtPowerInformation() again and pass SystemPowerCapabilities to InformationLevel parameter; but now, set lpInputBuffer to the SYSTEM_POWER_CAPABILITIES structure in which the two members has been set to 100%. I'm sure you know what to do next.
In non-programmatic way, you can also get/set Windows Power Options using the Windows built-in command-line tools, that is, PowerCfg.
Further Reading
Power Management
Power Management Functions
So far, none of the above CallNtPowerInformation options worked for me. The relevant ProcessorThrottle field of SYSTEM_POWER_CAPABILITIES was FALSE and changing some SYSTEM_POWER_POLICYs didn't work.
However, https://www.geeks3d.com/20170213/how-to-disable-intel-turbo-boost-technology-on-a-notebook/#_24 outlines a way to make an option available in the power management settings.
With ProcMon, I was able to trace it back to the following registry manipulations:
Read the ActivePowerScheme SZ value under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\User\PowerSchemes to get the active power plan
Set the ACSettingIndex and/or DCSettingIndex DWORD under Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\User\PowerSchemes\<above active power plan GUID>\54533251-82be-4824-96c1-47b60b740d00\be337238-0d82-4146-a960-4f3749d470c7 to 0 (Disabled, or whatever you choose) from 2 (High)
Unfortunately, the relevant keys are owned by the system, which either means you have to prompt the user (which has to have admin access) to change the permissions of the key or you have to use powercfg to manipulate the setting. The latter is preferrable and actually seems to work, even without admin access (courtesy of https://learn.microsoft.com/en-us/windows-server/administration/performance-tuning/hardware/power/power-performance-tuning#processor-performance-boost-mode):
powercfg -setacvalueindex scheme_current sub_processor PERFBOOSTMODE 0
powercfg -setdcvalueindex scheme_current sub_processor PERFBOOSTMODE 0
powercfg -setactive scheme_current
In Windows XP and later CPU speed is managed by power policy. Doesn't it turn off the scaling if you set "Max performance" mode in Windows power management dialog?
There're also some third party tools - SpeedSwitchXP for example.
Programmatically this could be done, I suppose, using CallNtPowerInformation function.
Related
Recently I need to monitor the battery consumption of some process.
The method I already know is to get it through top:
top -stats pid,command,cpu,idlew,power -o power -d
In addition, it can also be obtained in the Activity Monitor of macOS, but I do not know whether there is an operating system interface, so that I can directly obtain a relative value of the power consumption of a process.
I tried to use proc_pid_rusage. The returned parameters are ri_billed_energy and ri_serviced_energy, but they are always 0. I want to know if there are other interfaces or methods that allow me to get this value.
There seems to be two methods of setting and getting a user screensaver parameters on a Windows platform:
1: Via the SystemParametersInfo() API:
//To read
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &bScreensaverAcrtive, NULL);
SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &nScreensaverTimeout, NULL);
//No API to get the screensaver file used
//To set
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, bScreensaverAcrtive, NULL);
SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, 0, nScreensaverTimeout, NULL);
//No API to change the screensaver file
2: Through the system registry keys:
HKCU\Control Panel\Desktop - "ScreenSaveActive"
HKCU\Control Panel\Desktop - "ScreenSaveTimeOut"
HKCU\Control Panel\Desktop - "SCRNSAVE.EXE"
But since there're two competing methods that seem to do the same, what is the recommended way to use?
PS. I highly favor method #2 (or writing directly into registry) due to the following reasons:
A. If you read the explanation of a bug in the SPI_GETSCREENSAVEACTIVE flag, you'll see that MS themselves recommend to use registry.
B. If you read the documentation for the SPI_SETSCREENSAVEACTIVE and SPI_SETSCREENSAVETIMEOUT flags, there's this mystical line that says, "*If the machine has entered power saving mode or system lock state, an ERROR_OPERATION_IN_PROGRESS exception occurs.*" I first ignored this situation until it actually started happening on my test installation of Windows 8. This is the most asinine error, I should tell you. There's absolutely no graceful way of interpreting what it means or do any workaround (except, writing directly into the registry.)
Use the API. Asking that is like asking if you should wait for the traffic light to turn green before crossing the road. I won't call the cops if I see you crossing at red, but if you ask me, I'll tell you you have to wait. And you are the one taking the risk of bad things happening.
The API is documented, the registry locations are not. Microsoft is in no obligation to preserve the registry locations or their functionality.
The SPI_GETSCREENSAVEACTIVE flag affects Windows 2000. If you support Windows 2000 as a target platform, I would apply the registry read to that version only (OSVERSIONINFO.dwMajor=5, .dwMinor=0)
ERROR_OPERATION_IN_PROGRESS I'd try to figure out under what circumstances this happens (e.g. screensaver already active, or system about to enter a power saving state).
Generally, I'd find it questionable if activating / deactivating the screensaver is not at least related to a user action, in which case the system should be ready to accept a change.
What are you trying to achieve? Why do you need to modify screensaver activity? Maybe there's some better method to achieve your goal
Use the API. The registry format changes often.
As for the power state changes, screen savers are really a 20th century feature. Laptops turn off the screen entirely, for obvious reasons. In that power saving state SPI_SETSCREENSAVEACTIVE obviously should fail. Not a lot of interpreting to do.
So, check for GUID_VIDEO_POWERDOWN_TIMEOUT first.
edit
I just realized that Group Policy screensavers are also unlikely to be in the registry, and certainly would override HKCU. Not a real issue for Windows 2000, of course, but today the API method would be even more advisable. Of course, do realize that this is just another reason why SPI_SETSCREENSAVEACTIVE may return an error. Still an improvement over the registry approach, which fails silently in the presence of Group Policy.
"To set" above is incorrect. It should be:
//To set
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, bScreensaverAcrtive, NULL, NULL);
SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, nScreensaverTimeout, NULL, NULL);
I've tried the Win32_DesktopMonitor and checked the "Availability", but the value returned is always 3 (powered on), even when the monitor is physically turned off.
Is the data cached and there's a "force refresh" command in WMI, or in this particular case, the "Availability" is just not reliable ?
I think there is caching going on somewhere. I've observed it recently.
I wrote code that was polling for updates to Win32_PnPSignedDriver via SelectQuery / ManagementObjectSearcher and the results appear to be cached because it never realizes that a new device/driver has been added. Running the query from a separate app instantly sees that it was updated.
You may have a look to your driver. According to the documentation, starting with Windows Vista, hardware that is not compatible with Windows Display Driver Model (WDDM) returns inaccurate property values for instances of this class. For me it's an another way to say that it's not reliable.
I have a C++ program that launches various MS Access databases (.mdb files), some of which have Startup Restrictions applied to them.
Right now, the only way I know to disable those restrictions is to hold down the shift key until the database finishes loading.
I want my program to simulate the same end result of opening the database with those restrictions disabled, but I don't want to have to make the user hold down the shift key, and I don't want to simulate the shift key myself in the program. It's been my experience that you have to hold the shift key down until the database finishes loading, and that doesn't always take the same amount of time (in my environment anyways). So, I don't see that as a very reliable option.
Does anyone know another approach I could take besides simulating the shift key?
I have looked into the AllowBypassKey property in Access, but even if you set that to true, it still requires the user to hold down the shift key in order to disable the startup options.
I currently use ShellExecute() to launch the database, but I'm open to using another method.
Note: The solution needs to work in Access 2000, 2003, 2007, and 2010
I have two programs, one in C++, the other in assembler. I want to compare how much memory they use when running respectively. How can I do this?
I am doing the testing on Windows, but I also would like to know how to do it on Linux.
On Linux, try valgrind. It's an amazing tool with too many features for mere mortals to totally comprehend. Have a look at valgrind's massif.
Run the program in one shell. Open another shell and run 'top' command. it will list running processes and home much memory they consume. you can, i guess, poll /proc/yourprocessid/stat to see how much memory it is using over time.
On Windows you can use Performance Monitor.
Performance monitor usage
Start Performance Monitor from Start menu/ Administrative Tools/ Performance
If you want to start the logging:
Select performance log and alert>Current Log option in the left side of the browser.
Select New Log Settings.
Give an apropriate name to the log e.g. performance_Server for Server
It will prompt you one menu. In “general” tabs click on the add button and select the process you want monitor. (Change the performance object to process, for “select counters from list” select “private bytes”, for “select instances from list”, select the process you want to monitor.) After that click on Add and close. Now change the interval as per test case requirement. Now go to “log files” tab change the log file type to either csv or tsv format. Now apply and press OK.
If you want to start/stop the logging:
Select the particular log you want to start and stop.
In toolbar above you will see start and stop button.
If you want to check the content of a log file:
Click Options/Data From…
Select the log file to be viewed, click OK
Go to the chart screen (View/Chart)
Click Edit/Add to chart
Add the required items to the chart. (In case the memory leakage is to be checked, then you need to view the PrivateBytes of the processes and the _Total of them)
Read the values from the chart (Min and Max values are displayed at the bottom of the chart)
If you want to monitor network transfer:
Display the chart screen (View/Chart)
Click Edit/Add to log, and select the items Network Interface\Bytes Sent If you set it in dl
Or Network Inerface\ Bytes Received if you set it in the CRS-PC+
Click Done
Monitor memory usage:
In menu Start/Programs/Administrative Tools/ start the program Performance Monitor
Click on the button to open the window that adds processes
Fill the fields as follows:
Object: Process
Counter: Private Bytes
Instance: a process whose Memory occupation need to be displayed
Click on Add button
Repeat the last two steps for every process the memory needs to be displayed
Close the window that adds processes
On the bottom of the Performance Monitor window, there is the list of the processes previously selected.
How to use the logged data
Now open the file Perfmon_.csv or Perfmon_.tsv using WordPad or Excel.
If you have opened the file using Excel, then using the option Save As, save the file in the Microsoft Excel format.
The Windows Task manager can show you the memory usage of each process. I guess you could use Valgrind instead, but I don't see the point in that. On Linux, use Valgrind or ps.
On Windows you can use the GetProcessMemoryInfo Function.
Here is an example on how to use it:
Collecting Memory Usage Information For a Process
Depends on your operating system - you would expect to have tools to tell you the memory consumed when the apps are running.
Trying to infer the answer by inspecting the code would be very difficult, run the apps, use your platform's diagnoistics.
Depending on the size of the programs, this could be nearly unfeasible.
If they are not very large, then you can see how much memory they allocate; for instance, an int would take up 4 bytes, a char would take 1 byte, etc. Assembly is very transparent in how much memory it is using, even on an x86 machine. Cpp is nearly as transparent, as long as you faithfully track object creation and memory destruction/allocation.
If the program is huge, you'll need to use specific tools for tracking/profiling memory use, like GlowCode (http://www.glowcode.com/summary.htm).
On Windows, you can use Microsoft's Performance Monitor to do it. Start, Run, "perfmon". This tool will report on all sorts of statistics about processes, and provide graphs for you. In general, you're going to be interested in reporting on the "Private working set". This will tell you how much memory your process has reserved for its own use.
If you want to just get your heap usage, and you want to do it programatically, you should look into the CRT Debug Heap.
I'm not sure about Linux though, sorry.
On Windows, I have found Address Space Monitor very useful, especially for looking at how fragmented your memory is.