I wrote a simple moving average with a moving window of Temperatures read as a voltage between 0 and 10V.
The algorithm appears to work correctly, however, it has a problem where depending upon which Temperatures filled the window first, the moving average will have an offset for any values not near this value. For example, running this program with the temp. sensor plugged in a room temp yields 4.4V or 21.3 C. Though, if I unplug the temp. sensor the voltage drops to 1.4V yet the moving average stays at 1.6V. This offset becomes smaller as I increase the size of the window. How remove this offset even for small window sizes eg. 20 ?
REM SMA Num Must be greater than 1
#DEFINE SMANUM 20
PROGRAM
'Program 3 - Simple Moving Average Test
CLEAR
DIM SA(1)
DIM SA0(SMANUM) : REM Moving Average Window as Array
DIM LV1
DIM SV2
LV0 = 0 : REM Counter
SV0 = 0 : REM Average
SV1 = 0 : REM Sum
WHILE(1)
SA0(LV0 MOD SMANUM) = PLPROBETEMP : REM add Temperature to head of window
SV1 = SV1 + SA0(LV0 MOD SMANUM) : REM add new value to sum
IF(LV0 >= (SMANUM)) : REM check if we have min num of values
SV1 = SV1 - SA0((LV0+1) MOD SMANUM) : REM remove oldest value from sum
SV0 = SV1 / SMANUM : REM calc moving average
PRINT "Avg: " ; SV0 , " Converted: " ; SV0 * 21.875 - 75
ENDIF
LV0 = LV0 + 1 : REM increment counter
WEND
ENDP
(Note this is written in ACROBASIC for the ACR9000 by Parker)
Output - Temp Sensor attached
Raw: 4.43115 Avg: 4.41926 Converted: 21.6713125
Raw: 4.43115 Avg: 4.41938 Converted: 21.6739375
Raw: 4.43359 Avg: 4.41963 Converted: 21.67940625
Raw: 4.43359 Avg: 4.41987 Converted: 21.68465625
Raw: 4.43359 Avg: 4.42012 Converted: 21.690125
Raw: 4.43359 Avg: 4.42036 Converted: 21.695375
Raw: 4.43359 Avg: 4.42061 Converted: 21.70084375
...remove temp sensor while program is running
Raw: 1.40625 Avg: 1.55712 Converted: -40.938
Raw: 1.40381 Avg: 1.55700 Converted: -40.940625
Raw: 1.40625 Avg: 1.55699 Converted: -40.94084375
Raw: 1.40625 Avg: 1.55699 Converted: -40.94084375
Raw: 1.40381 Avg: 1.55686 Converted: -40.9436875
Raw: 1.40381 Avg: 1.55674 Converted: -40.9463125
Raw: 1.40625 Avg: 1.55661 Converted: -40.94915625
A noticeable offset appears between the raw and moving average after removing the sensor.
The offset also occurs in the reverse order:
Output - Begin program w/ Temp Sensor removed
Raw: 1.40381 Avg: 1.40550 Converted: -44.2546875
Raw: 1.40625 Avg: 1.40550 Converted: -44.2546875
Raw: 1.40625 Avg: 1.40549 Converted: -44.25490625
Raw: 1.40625 Avg: 1.40549 Converted: -44.25490625
Raw: 1.40625 Avg: 1.40548 Converted: -44.255125
Raw: 1.40625 Avg: 1.40548 Converted: -44.255125
... attach temp sensor while program is running
Raw: 4.43848 Avg: 4.28554 Converted: 18.7461875
Raw: 4.43848 Avg: 4.28554 Converted: 18.7461875
Raw: 4.43848 Avg: 4.28554 Converted: 18.7461875
Raw: 4.43848 Avg: 4.28554 Converted: 18.7461875
Raw: 4.43848 Avg: 4.28554 Converted: 18.7461875
Raw: 4.43359 Avg: 4.28530 Converted: 18.7409375
Again noticeable offset appears between the raw and moving average after attaching the sensor.
The problem seems to be that the value that was being subtracted from the sum was not actually the oldest value in the array -- the oldest value was, in fact, overwritten by the new value in the first line of the WHILE loop. It was the second-oldest value that was being subtracted from the sum.
EDIT Changed Average and Sum variable to 64-bit floating point to address precision loss over time, on the OP's advice.
Ensuring that the oldest value is subtracted first (once the array is full) gives the expected answer:
PROGRAM
'Program 3 - Simple Moving Average Test
CLEAR
DIM SA(1)
DIM SA0(SMANUM) : REM Moving Average Window as Array
DIM LV1
DIM DV2
LV0 = 0 : REM Counter
DV0 = 0 : REM Average
DV1 = 0 : REM Sum
WHILE(1)
IF(LV0 >= (SMANUM)) : REM check if we have min num of values
DV1 = DV1 - SA0(LV0 MOD SMANUM) : REM remove oldest value from sum
ENDIF
SA0(LV0 MOD SMANUM) = PLPROBETEMP : REM add Temperature to head of window
DV1 = DV1 + SA0(LV0 MOD SMANUM) : REM add new value to sum
IF(LV0 >= (SMANUM)) : REM check if we have min num of values
DV0 = DV1 / SMANUM : REM calc moving average
PRINT "Avg: " ; DV0 , " Converted: " ; DV0 * 21.875 - 75
ENDIF
LV0 = LV0 + 1 : REM increment counter
WEND
I don't have a running BASIC environment but I tested this in Python and got the same incorrect output for code equivalent to your version and the expected output for code equivalent to the version that I've inserted above.
Related
I am trying to calculate a range of percentiles (5th-99th) in Bash for a text file that contains 5 values, one per line.
Input
34.5
32.2
33.7
30.4
31.8
Attempted Code
awk '{s[NR-1]=$1} END{print s[int(0.05-0.99)]}' input
Expected Output
99th 34.5
97th 34.4
95th 34.3
90th 34.2
80th 33.9
70th 33.4
60th 32.8
50th 32.2
40th 32.0
30th 31.9
20th 31.5
10th 31.0
5th 30.7
For calculation of percentile based on 5 values, one need to create a mapping between percentiles, and to interpolate between them. A process called 'Piecewise Linear function' (a.k.a. pwlf).
F(100) = 34.5
F(75) = 33.7
F(50) = 32.2
F(25) = 31.8
F(0) = 30.4
Mapping of any other x in the range 0..100, require linear interpolation betweeh F(L), and F(H) - where L is the highest value >= x, and H=L+1.
awk '
#! /bin/env awk
# PWLF Interpolation function, take a value, and two arrays for X & Y
function pwlf(x, px, py) {
# Shortcut to calculate low index of X, >= p
p_l = 1+int(x/25)
p_h = p_l+1
x_l = px[p_l]
x_h = px[p_h]
y_l = py[p_l]
y_h = py[p_h]
#print "X=", x, p_l, p_h, x_l, x_h, y_l, y_h
return y_l+(y_h-y_l)*(x-x_l)/(x_h-x_l)
}
# Read f Input in yy array, setup xx
{ yy[n*25] = $1 ; n++ }
# Print the table
END {
# Sort values of yy
ny = asort(yy) ;
# Create xx array 0, 25, ..., 100
for (i=1 ; i<=ny ; i++) xx[i]=25*(i-1)
# Prepare list of requested results
ns = split("99 97 95 90 80 70 60 50 40 30 20 10 5", pv)
for (i=1 ; i<=ns ; i++) printf "%dth %.1f\n", pv[i], pwlf(pv[i], xx, yy) ;
}
' input
Technically a bash script, but based on comments to OP, better to place the whole think into script.awk, and execute as one lines. Solution has the '#!' to invoke awk script.
/path/to/script.awk < input
I'm struggling to understand how JMeter summariser works:
03:06:30 [debug] summary = 73930 in 1523s = 48.5/s Avg: 174 Min: 9 Max: 33133 Err: 4 (0.01%)
03:07:01 [debug] summary + 1573 in 78.2s = 20.1/s Avg: 142 Min: 10 Max: 2428 Err: 1 (0.06%) Active: 1600 Started: 1600 Finished: 0
03:07:01 [debug] summary = 75503 in 1555s = 48.6/s Avg: 173 Min: 9 Max: 33133 Err: 5 (0.01%)
03:07:30 [debug] summary + 1538 in 82.3s = 18.7/s Avg: 118 Min: 10 Max: 2704 Err: 0 (0.00%) Active: 1600 Started: 1600 Finished: 0
03:07:30 [debug] summary = 77041 in 1583s = 48.7/s Avg: 172 Min: 9 Max: 33133 Err: 5 (0.01%)
I have 73930 transactions executed in 1523s, which gives average of 48.5/s. Then two bunches of transactions are added on top of that:
1573 in 78.2s = 20.1/s
1538 in 82.3s = 18.7/s
Note the averages - 20.1/s and 18.7/s are below initial 48.5/s. I'd expect those to decrease overall statistics, but it goes up instead, by 0.2/s:
77041 in 1583s = 48.7/s
What I can see is: transactions are added as I'd expect (e.g. 73930 + 1573 = 75503), but how 1523s become 1555s and then 1583 is not clear to me.
Can someone explain that to me?
From the above given logs, it is clear that you have completed the execution of 73930 transactions at 03:06:30. Then 3111(1573+1538) transactions were executed by 03:07:30. So the extra 3111 transactions has taken a time of 60 sec. Which gets added to the original time 1523s. So 1523+60=1583.
It is not summing the time taken for the extra transactions as we sum the extra transactions to the original number of transactions(73930).
You can sum 73930+1573 and then get the total sum as 75503. But you should not sum the time as 1523s+78.2s. The time it is calculating is coming from the original time stamp.
I have a simple JMeter throughput test that spawns 20 threads and each thread executes a simple SQL query against a database. I have set a ramp up time of 10 seconds and a total test time of 70 seconds.
When I execute the test in non-GUI mode I see the following summary output:
summary + 1 in 0.1s = 7.4/s Avg: 135 Min: 135 Max: 135 Err: 0 (0.00%) Active: 1 Started: 1 Finished: 0
summary + 137501 in 28.5s = 4831.0/s Avg: 3 Min: 1 Max: 614 Err: 0 (0.00%) Active: 20 Started: 20 Finished: 0
summary = 137502 in 29s = 4796.9/s Avg: 3 Min: 1 Max: 614 Err: 0 (0.00%)
summary + 171000 in 30s = 5703.8/s Avg: 3 Min: 1 Max: 519 Err: 0 (0.00%) Active: 20 Started: 20 Finished: 0
summary = 308502 in 59s = 5260.8/s Avg: 3 Min: 1 Max: 614 Err: 0 (0.00%)
summary + 61016 in 11.5s = 5309.0/s Avg: 3 Min: 1 Max: 518 Err: 0 (0.00%) Active: 0 Started: 20 Finished: 20
summary = 369518 in 70.1s = 5268.9/s Avg: 3 Min: 1 Max: 614 Err: 0 (0.00%)
As you can see that the throughput is low in the first 30 seconds but picks up later. I understand that this could be due to the threads starting and other system components warming up.
Is there a way I can exclude "X" seconds worth of starting numbers from the final calculation. I have used some custom performance tests where I always excluded the first "X" seconds until the system reached a steady state before measuring the output.
Is there anyway I can do that in JMeter?
Option 1:
JMeter result file is basically CSV file having the following format:
timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,bytes,grpThreads,allThreads,Latency
1440671556283,1799,HTTP Request,200,OK,Thread Group 1-1,text,true,1591,1,1,1798
where first column is sample start time (in milliseconds since Unix Time)
If you need to omit first 30 seconds add 30000 to the first sampler timestamp, locate the closest row and delete all the rows from 1st to that one.
Option 2:
You can use Synchronizing Timer to ensure that load starts with 20 threads from the early beginning.
You can use jmeter-plugins to generate graphs
http://jmeter-plugins.org/wiki/GraphsGeneratorListener/
And fill in start offset field.
Read this for using generation:
https://www.ubik-ingenierie.com/blog/automatically-generating-nice-graphs-at-end-of-your-load-test-with-apache-jmeter-and-jmeter-plugins/
I need to generate repeatable pseudo random numbers based on a set of coordinates, so that with a given seed, I will always generate the same value for a specific coordinate.
I figured I'd use something like this for the seed:
/* 64bit seed value*/
struct seed_cord {
uint16 seed;
uint16 coord_x_int;
uint16 coord_y_int;
uint8 coord_x_frac;
uint8 coord_y_frac;
}
Where coord_x_int is the integer part of the coordinate, and the fraction part is given by coord_x_frac / 0xFF. seed is a randomly pre-determined value.
But I must admit, trying to understand all the intricacies of PRNGs is a little overwhelming. What would be a good generator for what I'm attempting?
I tested out Java's PRNG using using this scheme in a quick groovy script, with the following result:
Obviously, this is hardly decent randomness.
The script I used was:
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
short shortSeed = new Random().next(16) as short
def image = new BufferedImage(512, 512, BufferedImage.TYPE_BYTE_GRAY)
def raster = image.getRaster()
//x
(0..1).each{ x ->
(0..255).each{ xFrac ->
//y
(0..1).each{ y ->
(0..255).each{ yFrac ->
long seed = (shortSeed as long) << 48 |
(x as long) << 32 |
(y as long) << 16 |
(xFrac as long) << 8 |
(yFrac as long)
def value = new Random(seed).next(8)
raster.setSample( (x? xFrac+256 : xFrac), (y? yFrac+256 : yFrac), 0 , value)
}}}}
ImageIO.write(image, "PNG", new File("randomCoord.png"))
If you're really only looking at 512x512, then that's uh... 218 pixels you're interested in.
There's plenty of space for that kind of population with good ole MD5 (128 bit output).
You can just take the lowest 32 bits for an integer if that's the kind of output you need. Really, any sort of hashing algorithm that has an output space at least as large as an int will do.
Now, you can do all sorts of fun stuff if you're paranoid. Start with a hash of your coordinates, then feed the result into a secure random number generator (java.security.SecureRandom). Then hash it 1000 times with a salt that's your birthday concatenated (x+y) times.
Joking aside, random number generators don't necessarily have wildly varying results based on small variations of the seed. They're designed to have a really, super duper long chain of generated numbers before they start repeating, while having those chains pretty evenly distributed among the number space.
On the other hand, the SecureRandom is designed to have the additional feature of being chaotic in regard to the seed.
Most languages have a PRNG package (or two) that lets you initialize the generator with a specific seed. PRNGs can also often be found as part of a larger cryptographic package; they tend to be a bit stronger than those found in general-purpose libraries.
I would take a program like this one I have created and then modify it to pick coordinates:
REM $DYNAMIC
COMMON SHARED n%, rbuf%, sz%, sw%, p1$
DECLARE SUB initialize ()
DECLARE SUB filbuf ()
DECLARE SUB setup ()
DECLARE FUNCTION Drnd# ()
DECLARE SUB core ()
DECLARE SUB modify ()
DIM SHARED pad1(340) AS STRING * 1
DIM SHARED trnsltr(66) AS STRING * 1 ' translates a 0-67 value into a pad character
DIM SHARED trnslt(255) AS INTEGER 'translates a pad value to 0-67 value -1 if error
DIM SHARED moders(26) AS INTEGER 'modding function prim number array
DIM SHARED moders2(26) AS INTEGER 'modding function prim number array
DIM SHARED ranbuf(1 TO 42) AS DOUBLE 'random number buffer if this is full and rbuf %>0
REM then this buffer is used to get new random values
REM rbuf% holds the index of the next random number to be used
REM subroutine setup loads the prime number table
REM from the data statements to be used
REM as modifiers in two different ways (or more)
REM subroutine initialize primes the pad array with initial values
REM transfering the values from a string into an array then
REM makes the first initial scrambling of this array
REM initializing pad user input phase:
CLS
INPUT "full name of file to be encrypted"; nam1$
INPUT "full name of output file"; nam2$
INPUT "enter password"; p2$
rbuf% = 0
n% = 0: sw% = 0
p3$ = STRING$(341, "Y")
p1$ = "Tfwd+-$wiHEbeMN<wjUHEgwBEGwyIEGWYrg3uehrnnqbwurt+>Hdgefrywre"
p1$ = p2$ + p1$ + p3$
PRINT "hit any key to continue any time after a display and after the graphic display"
p1$ = LEFT$(p1$, 341)
sz% = LEN(p1$)
CALL setup
CALL initialize
CLS
ibfr$ = STRING$(512, 32)
postn& = 1
OPEN nam1$ FOR BINARY AS #1
OPEN nam2$ FOR BINARY AS #2
g& = LOF(1)
max& = g&
sbtrct% = 512
WHILE g& > 0
LOCATE 1, 1
PRINT INT(1000 * ((max& - g&) / max&)) / 10; "% done";
IF g& < 512 THEN
ibfr$ = STRING$(g&, 32)
sbtrct% = g&
END IF
GET #1, postn&, ibfr$
FOR ste% = 1 TO LEN(ibfr$)
geh% = INT(Drnd# * 256)
MID$(ibfr$, ste%, 1) = CHR$(geh% XOR ASC(MID$(ibfr$, ste%, 1)))
NEXT ste%
PUT #2, postn&, ibfr$
postn& = postn& + sbtrct%
g& = g& - sbtrct%
WEND
CLOSE #2
CLOSE #1
PRINT "hit any key to exit"
i$ = ""
WHILE i$ = "": i$ = INKEY$: WEND
SYSTEM
END
DATA 3,5,7,9,11,13,17,19
DATA 23,29,33,37,43,47
DATA 53,59,67,71,73,79,83
DATA 89,91,97,101,107,109
DATA 43,45,60,62,36
REM $STATIC
SUB core
REM shuffling algorythinm
FOR a% = 0 TO 339
m% = (a% + 340) MOD 341: bez% = trnslt(ASC(pad1(340)))
IF n% MOD 3 = 0 THEN pad1(340) = trnsltr((2 * trnslt(ASC(pad1(a%))) + 67 - trnslt(ASC(pad1(m%)))) MOD 67)
IF n% MOD 3 = 1 THEN pad1(340) = trnsltr((2 * (67 - trnslt(ASC(pad1(a%)))) + 67 - trnslt(ASC(pad1(m%)))) MOD 67)
IF n% MOD 3 = 2 THEN pad1(340) = trnsltr(((2 * trnslt(ASC(pad1(a%))) + 67 - trnslt(ASC(pad1(m%)))) + moders(n% MOD 27)) MOD 67)
pad1(a% + 1) = pad1(m%): n% = (n% + 1) MOD 32767
pad1(a%) = trnsltr((bez% + trnslt(ASC(pad1(m%)))) MOD 67)
NEXT a%
sw% = (sw% + 1) MOD 32767
END SUB
FUNCTION Drnd#
IF rbuf% = 0 THEN
CALL core
CALL filbuf
IF sw% = 32767 THEN CALL modify
END IF
IF rbuf% > 0 THEN yut# = ranbuf(rbuf%)
rbuf% = rbuf% - 1
Drnd# = yut#
END FUNCTION
SUB filbuf
q% = 42: temp# = 0
WHILE q% > 0
FOR p% = 1 TO 42
k% = (p% - 1) * 8
FOR e% = k% TO k% + 7
temp# = temp# * 67: hug# = ABS(trnslt(ASC(pad1(e%)))): temp# = temp# + hug#
NEXT e%
IF temp# / (67 ^ 8) >= 0 AND q% < 43 THEN
ranbuf(q%) = temp# / (67 ^ 8): q% = q% - 1
END IF
temp# = 0
NEXT p%
WEND
rbuf% = 42
END SUB
SUB initialize
FOR a% = 0 TO 340
pad1(a%) = MID$(p1$, a% + 1, 1)
NEXT a%
FOR a% = 0 TO 340
LOCATE 1, 1
IF a% MOD 26 = 0 THEN PRINT INT((340 - a%) / 26)
sum% = 0
FOR b% = 0 TO 340
qn% = INT(Drnd# * 81)
op% = INT(qn% / 3)
qn% = qn% MOD 3
IF qn% = 0 THEN sum% = sum% + trnslt(ASC(pad1(b%)))
IF qn% = 1 THEN sum% = sum% + (67 + 66 - trnslt(ASC(pad1(b%)))) MOD 67
IF qn% = 2 THEN sum% = sum% + trnslt(ASC(pad1(b%))) + moders(op%)
NEXT b%
pad1(a%) = trnsltr(sum% MOD 67)
NEXT a%
n% = n% + 1
END SUB
SUB modify
REM modifier shuffling routine
q% = 26
temp# = 0
WHILE q% > -1
FOR p% = 1 TO 27
k% = (p% - 1) * 4 + 3
FOR e% = k% TO k% + 3
temp# = temp# * 67
hug# = ABS(trnslt(ASC(pad1(e%))))
temp# = temp# + hug#
NEXT e%
IF (temp# / (67 ^ 4)) >= 0 AND q% > -1 THEN
SWAP moders(q%), moders(INT(27 * (temp# / (67 ^ 4))))
q% = q% - 1
END IF
temp# = 0
NEXT p%
WEND
END SUB
SUB setup
FOR a% = 0 TO 26
READ moders(a%)
moders2(a%) = moders(a%)
NEXT a%
REM setting up tables and modder functions
FOR a% = 0 TO 25
trnsltr(a%) = CHR$(a% + 97)
trnsltr(a% + 26) = CHR$(a% + 65)
NEXT a%
FOR a% = 52 TO 61
trnsltr(a%) = CHR$(a% - 4)
NEXT a%
FOR a% = 62 TO 66
READ b%
trnsltr(a%) = CHR$(b%)
NEXT a%
FOR a% = 0 TO 255
trnslt(a%) = -1
NEXT a%
FOR a% = 0 TO 66
trnslt(ASC(trnsltr(a%))) = a%
NEXT a%
RESTORE
END SUB
the call to drand# gives you random numbers from 0 to 1 simply multiply that by your needed range for each vector needed p2$ is the password that is passed to the password handler which combines it with some other random characters and then caps the size to a certain limit p1$ is where the final modified password is contained
drand# itself calls another sub which is actually a clone of itself with some shuffling of
sorts that works to ensure that the numbers being produced are truly random there is also a table of values that are added in to the values being added all this in total makes the RNG many many more times random with than without.
this RNG has a very high sensitivity to slight differences in password initially set you must however make an intial call to setup and initialize to "bootstrap" the random number generator this RNG will produce Truly random numbers that will pass all tests of randomness
more random even then shuffling a deck of cards by hand , more random than rolling a dice..
hope this helps using the same password will result in the same sequnece of vectors
This program would have to be modified a bit though to pick random vectors rather than
it's current use as a secure encryption random number generator...
You can use encryption for this task, for example AES. Use your seed as the password, struct with coordinates as the data block and encrypt it. The encrypted block will be your random number (you can actually use any part of it). This approach is used in the Fortuna PRNG. The same approach can be used for disk encryption where random access of data is needed (see Random access encryption with AES In Counter mode using Fortuna PRNG:)
I've written a little VBScript program to query the page file usage under Windows XP (eventually 2003/2008 Server as well) but the figures I seem to be getting are bizarre.
This is the program:
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
for i = 1 to 10
Set qry1 = wmi.ExecQuery ("Select * from Win32_PageFileSetting")
Set qry2 = wmi.ExecQuery ("Select * from Win32_PerfRawData_PerfOS_PagingFile")
initial = 0
maximum = 0
For Each obj in qry1
initial = initial + obj.InitialSize
maximum = maximum + obj.MaximumSize
Next
For Each obj in qry2
if obj.Name = "_Total" then
Wscript.Echo _
" Initial size: " & initial & _
" Maximum size: " & maximum & _
" Percent used: " & obj.PercentUsage & _
""
end if
Next
qry1 = none
qry2 = none
WScript.sleep (1000)
Next
which outputs:
Initial size: 1512 Maximum size: 3024 Percent used: 21354
Initial size: 1512 Maximum size: 3024 Percent used: 21354
Initial size: 1512 Maximum size: 3024 Percent used: 21354
Initial size: 1512 Maximum size: 3024 Percent used: 21354
Initial size: 1512 Maximum size: 3024 Percent used: 21354
Initial size: 1512 Maximum size: 3024 Percent used: 21354
Initial size: 1512 Maximum size: 3024 Percent used: 21354
Initial size: 1512 Maximum size: 3024 Percent used: 21354
Initial size: 1512 Maximum size: 3024 Percent used: 21354
Initial size: 1512 Maximum size: 3024 Percent used: 21354
The doco on MSDN states:
PercentUsage
Data type: uint32
Access type: Read-only
Qualifiers:
DisplayName ("% Usage")
CounterType (537003008)
DefaultScale (0)
PerfDetail (200)
Percentage of the page file instance in use. For more information,
see the PageFileBytes property in Win32_PerfRawData_PerfProc_Process.
Now that seems pretty straight-forward. Why is my 3G page file using 21000% of it's allocated space? That would be about 630G but pagefile.sys is only about 1.5G (and my entire hard disk is only 186G).
Update:
When I get the same field from Win32_PerfFormattedData_PerfOS_PagingFile, I get a more reasonable value of 5 but that still doesn't seem to coincide with Task Manager, which shows 1.06G usage out of the 3G maximum.
You can't operate with the value directly like that.
The CounterType of the ProcessUsage property is 537003008, which according to this table corresponds to the PERF_RAW_FRACTION counter. Given the formula from the second link, we end up with something like this:
" Percent used: " & ((obj.PercentUsage * 100) / obj.PercentUsage_Base) & _