diff --git a/Frameworks/VMFleet/s2d-vmfleet.docx b/Frameworks/VMFleet/s2d-vmfleet.docx index ad233ae..656eb02 100644 Binary files a/Frameworks/VMFleet/s2d-vmfleet.docx and b/Frameworks/VMFleet/s2d-vmfleet.docx differ diff --git a/Frameworks/VMFleet/s2d-vmfleet.pdf b/Frameworks/VMFleet/s2d-vmfleet.pdf index 624defc..34a0704 100644 Binary files a/Frameworks/VMFleet/s2d-vmfleet.pdf and b/Frameworks/VMFleet/s2d-vmfleet.pdf differ diff --git a/Frameworks/VMFleet/sweep-cputarget.ps1 b/Frameworks/VMFleet/sweep-cputarget.ps1 index 0bf1ff0..dbe795f 100644 --- a/Frameworks/VMFleet/sweep-cputarget.ps1 +++ b/Frameworks/VMFleet/sweep-cputarget.ps1 @@ -42,7 +42,7 @@ $qoswindow = 5 # clean result file and set column headers del -Force $outfile -ErrorAction SilentlyContinue -'WriteRatio','QOS','AVCPU','IOPS' -join "`t" > $outfile +'WriteRatio','QOS','AVCPU','IOPS','AVRLat','AVWLat' -join "`t" > $outfile # make qos policy and reset Get-StorageQosPolicy -Name SweepQos -ErrorAction SilentlyContinue | Remove-StorageQosPolicy -Confirm:$false @@ -73,6 +73,13 @@ function get-pc( ($pc[$t0 .. $t1].CounterSamples.CookedValue | measure -Average).Average } +$pc = @('\Hyper-V Hypervisor Logical Processor(_Total)\% Total Run Time', + '\Processor Information(_Total)\% Processor Performance', + '\Cluster CSVFS(_Total)\reads/sec', + '\Cluster CSVFS(_Total)\avg. sec/read', + '\Cluster CSVFS(_Total)\writes/sec', + '\Cluster CSVFS(_Total)\avg. sec/write') + # limit the number of attempts per sweep (mix) to 4 per targeted cpu util $sweeplimit = ($cputargets.count * 4) @@ -102,10 +109,11 @@ foreach ($w in 0,10,30) { write-host -fore Cyan Starting loop with QoS target $qos $curaddspec = "$($addspec)w$($w)qos$qos" - start-sweep.ps1 -addspec $curaddspec -b 4 -o 32 -t 1 -w $w -p r -d 60 -warm 15 -cool 15 -pc '\Hyper-V Hypervisor Logical Processor(_Total)\% Total Run Time','\Processor Information(_Total)\% Processor Performance' + start-sweep.ps1 -addspec $curaddspec -b 4 -o 32 -t 1 -w $w -p r -d 60 -warm 15 -cool 15 -pc $pc # HACKHACK bounce collect - Get-ClusterSharedVolume |? { $_.SharedVolumeInfo.FriendlyVolumeName -match 'collect' } | Move-ClusterSharedVolume + Get-ClusterSharedVolume |? { $_.SharedVolumeInfo.FriendlyVolumeName -match 'collect' } | Move-ClusterSharedVolume + sleep 1 # get average IOPS at DISKSPD @@ -123,10 +131,37 @@ foreach ($w in 0,10,30) { $trt = get-pc $_ $center '\Hyper-V Hypervisor Logical Processor(_Total)\% Total Run Time' $ppc = get-pc $_ $center '\Processor Information(_Total)\% Processor Performance' $trt*$ppc/100 + + } | measure -Average).Average + # get average latency for central 60 seconds, all nodes + # note we must aggregate the product of av latency and iops per node to get total + # latency, and then divide by total iops to get whole-cluster average. + + $csvrtotal = 0 + $csvwtotal = 0 + + ($avrlat,$avwlat) = $(dir $result\*.blg |% { + + $csvrlat = get-pc $_ $center '\Cluster CSVFS(_Total)\avg. sec/read' + $csvwlat = get-pc $_ $center '\Cluster CSVFS(_Total)\avg. sec/write' + $csvr = get-pc $_ $center '\Cluster CSVFS(_Total)\reads/sec' + $csvw = get-pc $_ $center '\Cluster CSVFS(_Total)\writes/sec' + + $csvrtotal += $csvr + + $csvwtotal += $csvw + + [pscustomobject] @{ 'avrtime' = $csvrlat*$csvr; 'avwtime' = $csvwlat*$csvw } + + } | measure -Sum -Property avrtime,avwtime).Sum + + $avrlat /= $csvrtotal + $avwlat /= $csvwtotal + # capture results - $w,$qos,$avcpu,$iops -join "`t" >> $outfile + $w,$qos,$avcpu,$iops,$avrlat,$avwlat -join "`t" >> $outfile # archive results compress-archive -Path $(dir $result\* -Exclude *.zip) -DestinationPath $result\$curaddspec.zip @@ -135,7 +170,7 @@ foreach ($w in 0,10,30) { # stop within targetwindow% of cpu (+/- % of target) if (is-within $avcpu $cputarget $cputargetwindow) { - write-host -ForegroundColor Green Stopping in target window at $avcpu with QoS at $qos + write-host -ForegroundColor Green "Stopping in target window at $('{0:N2}' -f $avcpu) with QoS $qos" break } @@ -154,17 +189,17 @@ foreach ($w in 0,10,30) { } if ($inwindow) { - write-host -ForegroundColor Yellow Stopping in window of prior measurement at $avcpu with QoS at $qos + write-host -ForegroundColor Yellow "Stopping in window of prior measurement at $('{0:N2}' -f $avcpu) with QoS $qos" break } # stop if next qos target is less than initial if ($nextqos -lt $qosinitial) { - write-host -ForegroundColor Red Stopping with underflow targeting $nextqos less than initial $qosinitial + write-host -ForegroundColor Red "Stopping with underflow targeting $nextqos less than initial $qosinitial" break } - write-host -ForegroundColor Cyan Next loop targeting $nextqos + write-host -ForegroundColor Cyan "Loop acheived $('{0:N2}' -f $avcpu) @ QoS $qos v. target $cputarget - next loop targeting QoS $nextqos" # record this datapoint as measured, move along to the next $h[$qos] = 1 diff --git a/Frameworks/VMFleet/watch-cpu.ps1 b/Frameworks/VMFleet/watch-cpu.ps1 index f4ea94f..c055f96 100644 --- a/Frameworks/VMFleet/watch-cpu.ps1 +++ b/Frameworks/VMFleet/watch-cpu.ps1 @@ -122,7 +122,11 @@ if ($clip -lt 10) { $clip = 10 } +# set window and buffer size simultaneously so we don't have extra scrollbars +cls [console]::SetWindowSize($width,$clip + $legend.Count + 1) +[console]::BufferWidth = [console]::WindowWidth +[console]::BufferHeight = [console]::WindowHeight # scale divisions at x% # this should evenly divide 100% @@ -137,10 +141,12 @@ while ($true) { } # get all specific instances and count them into appropriate measurement bucket - (get-counter -ComputerName $ComputerName -SampleInterval $SampleInterval '\Hyper-V Hypervisor Logical Processor(*)\% Total Run Time').Countersamples |% { + (get-counter -ComputerName $ComputerName -SampleInterval $SampleInterval '\Hyper-V Hypervisor Logical Processor(*)\% Total Run Time','\Processor Information(_Total)\% Processor Performance').Countersamples |% { - if ($_.InstanceName -ne '_Total') { - $m[[int]($_.CookedValue/$div)] += 1 + if ($_.Path -match 'Processor Information') { + $pperf = $_.CookedValue/100 + } elseif ($_.InstanceName -ne '_Total') { + $m[[math]::Floor($_.CookedValue/$div)] += 1 } else { $total = $_.CookedValue } @@ -174,8 +180,9 @@ while ($true) { cls write-host -NoNewline ($lines + $legend -join "`n") - write-host -NoNewLine ("`n" + (center-pad ("{1} Total: {0:0.0}%" -f $total,$ComputerName) $width)) + write-host -NoNewLine ("`n" + (center-pad ("{2} Total: {0:0.0}% Normalized: {1:0.0}%" -f $total,($total*$pperf),$ComputerName) $width)) # move the cursor to indicate average utilization - [console]::SetCursorPosition([console]::WindowWidth*$total/100,[console]::CursorTop-$legend.Count) + # column number is zero based, width is 1-based + [console]::SetCursorPosition([math]::Floor(($width - 1)*$total/100),[console]::CursorTop-$legend.Count) } \ No newline at end of file diff --git a/README.md b/README.md index 29ac669..0bf67f5 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,11 @@ DISKSPD 2.0.17 5/01/2016 ## VM Fleet ## +VM Fleet 0.9 10/2017 (minor) + +* watch-cpu: now provides total normalized cpu utility (accounting for turbo/speedstep) +* sweep-cputarget: now provides average CSV FS read/write latency in the csv + VM Fleet 0.8 6/2017 * get-cluspc: add SMB Client/Server and SMB Direct (not defaulted in Storage group yet)