It is currently April 18th, 2024, 11:17 pm

Reducing CPU usage?

Get help with creating, editing & fixing problems with skins
ItsJustRyan
Posts: 81
Joined: October 25th, 2019, 1:20 am

Re: Reducing CPU usage?

Post by ItsJustRyan »

Hi!

It took a while but finished the skin. I ended up having a bunch of parenthesis everywhere among other issues brought up before, but here it is :P.
I also have no idea whether I did the RMSkin thing correctly.

Any feedback or suggestions would be nice!

(Would definitely suggest turning on hardware acceleration for this too)
You do not have the required permissions to view the files attached to this post.
User avatar
Yincognito
Rainmeter Sage
Posts: 7125
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Reducing CPU usage?

Post by Yincognito »

ItsJustRyan wrote: March 19th, 2023, 10:05 pm Hi!

It took a while but finished the skin. I ended up having a bunch of parenthesis everywhere among other issues brought up before, but here it is :P.
I also have no idea whether I did the RMSkin thing correctly.

Any feedback or suggestions would be nice!

(Would definitely suggest turning on hardware acceleration for this too)
There is something seriously wrong with some of the things in your skin, even after balala suggested to correct the obvious (and even in his version earlier). It just takes way too much CPU for what it should take. A few tests I made on balala's version and your finalized skin:
- without any other modification than setting the player to Winamp in my case, both balala and your version take around 70% of CPU
- even with all the 3 meters using images commented, the CPU still goes from my usual 3.5% (with my animated suite running too) to around 6%
- commenting out the W and H in the said meters results in a major CPU usage drop from 70% to 20%-30%
This is without the hardware acceleration (HA) turned on, because you're right, the questions still stand on why that much usage. It really doesn't matter if it's the CPU that takes the hit or the GPU helps it, or if the animation is done via fast update rate overall on the skin or ActionTimer (AT), these things just shouldn't happen, period. Personally, I worked a lot (or should I say, almost exclusively) with animations in Rainmeter and HA or AT are false problems. Using HA doesn't mean there isn't a huge performance issue to begin with, and the only advantage of AT is that it does animation on demand since otherwise the usage is either the same or even a tiny bit higher than when using a fast skin update rate.

The first thing to do is obviously not resizing images in Rainmeter via W and H, especially large images on a fast update rate. This is textbook approach for anyone familiar with how Rainmeter handles these things - just photoshop stuff to use the original image dimensions wherever possible, it avoid a huge peformance loss. The second thing to do is to build your skin carefully to maximize performance, and here small details like update dividers or the corrections made by balala regarding a single parent measure for scenarios using the parent-child system really matter - the key principle is, if you don't need something to update, do not update at all, bar the first time, and otherwise include only what is needed in the code. Just to give you an example, my recently released 3D Earth skin, while obviously also at times intensive when animating, can be set up to consume around 4.5% of my CPU at full size ... with my animated skin suite active (so 3.5% as a starting point) and HA turned off (!), and needless to say, there are some really complex stuff going on there, not just 3 relatively static images in the entire skin. Sure, it's not based on just Rainmeter, but still, you get the idea.

Now, I don't have much time tonight and tomorrow I'll be busy with other things, but I'll look into this (starting with balala's corrected version, as it's simpler and shorter) when I get the chance. The idea should be to get at most around 6% usage without HA on my system (that would be 2.5% alone, if subtracting my already active skin suite usage as the starting point) - anything more than that would be a sign of poor performance.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Active Colors
Moderator
Posts: 1251
Joined: February 16th, 2012, 3:32 am
Location: Berlin, Germany

Re: Reducing CPU usage?

Post by Active Colors »

Yincognito wrote: March 20th, 2023, 12:18 am - commenting out the W and H in the said meters results in a major CPU usage drop from 70% to 20%-30%
...
The first thing to do is obviously not resizing images in Rainmeter via W and H, especially large images on a fast update rate. This is textbook approach for anyone familiar with how Rainmeter handles these things - just photoshop stuff to use the original image dimensions wherever possible, it avoid a huge peformance loss.
Yes, that had to be done from the beginning. Resizing an image 50 times per one second is a heavy task.

I have suggested it earlier but seems the author didn't change this. https://forum.rainmeter.net/viewtopic.php?p=213054#p213054

Updating meters and child measures on-demand instead of updating them constantly is also the second thing I would suggest as well.

Example: read point 1 and 2 from my post here https://forum.rainmeter.net/viewtopic.php?p=206342#p206342

Further optimization read: https://forum.rainmeter.net/viewtopic.php?t=41228
ItsJustRyan
Posts: 81
Joined: October 25th, 2019, 1:20 am

Re: Reducing CPU usage?

Post by ItsJustRyan »

Yincognito wrote: March 20th, 2023, 12:18 am There is something seriously wrong with some of the things in your skin, even after balala suggested to correct the obvious (and even in his version earlier).
It just takes way too much CPU for what it should take.

- even with all the 3 meters using images commented, the CPU still goes from my usual 3.5% (with my animated suite running too) to around 6%
I might be wrong, but that's also because the skin also now does a whole lot more than just the turntable in the background, although maybe that doesn't have a huge impact on CPU. Stuff like time/dates, the file and folder view plugins, a "video player" (ticks a counter and changes frame although it doesnt seem to work on copy of the skin I sent), and audio level stuff (although that one I did make it so that if it isn't on screen, it shouldn't be running). To get that stuff just click on the wood background and it should show up.
Yincognito wrote: March 20th, 2023, 12:18 am - even with all the 3 meters using images commented, the CPU still goes from my usual 3.5% (with my animated suite running too) to around 6%
- commenting out the W and H in the said meters results in a major CPU usage drop from 70% to 20%-30%
Active Colors wrote: March 20th, 2023, 1:17 pm I have suggested it earlier but seems the author didn't change this. https://forum.rainmeter.net/viewtopic.php?p=213054#p213054
I'm not sure why it would do that because even though I did write W=1000 and H=1000 in the code, the images (assuming you're referring to the rotator meters) are also 1000x1000. There are a few static ones I scaled with rainmeter, but I believe (iirc) I set UpdateDivider=-1 for. For the rotator meters, is it because Rainmeter still tries to scale it despite it being already the correct size, and its merely an issue of removing redundant code like that?
Yincognito wrote: March 20th, 2023, 12:18 am The first thing to do is obviously not resizing images in Rainmeter via W and H, especially large images on a fast update rate. This is textbook approach for anyone familiar with how Rainmeter handles these things - just photoshop stuff to use the original image dimensions wherever possible, it avoid a huge peformance loss.
But I assume nothing can be done for something like album covers, especially when it's rotating?
Active Colors wrote: March 20th, 2023, 1:17 pm Yes, that had to be done from the beginning. Resizing an image 50 times per one second is a heavy task.
I could probably fix that by doing an OnUpdateChange=[Update the appropriate meters] on non spinning album covers, but like above question, what do I do if I have to both resize it and rotate it? Maybe a dummy meter that gets the image and resizes it, then somehow saves it in a buffer and then loads that for rotation instead? If that's possible it might be slightly beyond me. Idea came from one of the functions of the skin. It runs a python code that takes a photo from my webcam every few seconds and then shows it in the iPad. (I know I probably should have done the iPad and such in a separate skin but I just wanted everything in one, which is why its such a large skin.)
Active Colors wrote: March 20th, 2023, 1:17 pm Updating meters and child measures on-demand instead of updating them constantly is also the second thing I would suggest as well.
I did that for some things like folder (or file view, I forget which one) and audio level because I felt those would be more intensive than everything else (besides the animations of course). I wasn't entirely sure how the pause/stop measure bangs worked, so I ended up making a convoluted way of dynamically changing the UpdateDivider between -1 and whatever value. I could probably change some of the measures to more reasonable update rates for date and hour stuff for sure though.

It's definitely still a work in progress, I only spent a small amount of time really trying to reduce usage and mostly focused on putting stuff in that I wanted, with optimization only happening if I remember as I am writing the code. There are probably also much better ways of doing some of the stuff I've done in here, like the aforementioned variable updateDividers and such. I figured I should put an update of what I've got since it's been more than a week since the last post.
User avatar
balala
Rainmeter Sage
Posts: 16144
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Reducing CPU usage?

Post by balala »

ItsJustRyan wrote: March 20th, 2023, 2:55 pm I'm not sure why it would do that because even though I did write W=1000 and H=1000 in the code, the images (assuming you're referring to the rotator meters) are also 1000x1000.
Unfortunately the image used into a Rotator meter can't be resized by setting a W and H options on it, as you do with an Image meter. To resize this image, you have to use TransformationMatrix.
User avatar
Yincognito
Rainmeter Sage
Posts: 7125
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Reducing CPU usage?

Post by Yincognito »

Active Colors wrote: March 20th, 2023, 1:17 pm Yes, that had to be done from the beginning. Resizing an image 50 times per one second is a heavy task.

I have suggested it earlier but seems the author didn't change this. https://forum.rainmeter.net/viewtopic.php?p=213054#p213054

Updating meters and child measures on-demand instead of updating them constantly is also the second thing I would suggest as well.

Example: read point 1 and 2 from my post here https://forum.rainmeter.net/viewtopic.php?p=206342#p206342

Further optimization read: https://forum.rainmeter.net/viewtopic.php?t=41228
Rest assured, I did read your previous posts and agreed to what you said, I only meant to emphasize those points, avoid any misunderstanding on what and how things like these influence performance, and also what does not influence performance significantly overall (like choosing between fast skin update rate or ActionTimer, for example, whose role is more in the direction of saving performance but only when it comes to animating on demand, otherwise its usage being similar to the fast skin update rate).

The other links are good things to know indeed (me, I'm not too good at pointing out other topics where similar issues have been discussed, you probably know that already, haha!), there was some other thread that focused exactly on performance tips for Rainmeter but can't remember the author now to search it. Such a thread where there is a comprehensive and general analysis on performnace should be made sticky somewhere, because many skin designers sooner or later could make use of those tips and benefit from applying such "tricks".
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Yincognito
Rainmeter Sage
Posts: 7125
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Reducing CPU usage?

Post by Yincognito »

balala wrote: March 20th, 2023, 3:24 pm Unfortunately the image used into a Rotator meter can't be resized by setting a W and H options on it, as you do with an Image meter. To resize this image, you have to use TransformationMatrix.
That's true. That shouldn't matter though, since the TM usage is, just like the fast skin update rate and AT, quite similar (and I made a lot of tests on that, on other skins). Who knows, maybe the size of the rotator is the one that weighs more on this, because using TM shouldn't, it's quite performance friendly otherwise, to he honest.

For the record, none of my songs have actual cover art images, I deleted all unnecessary stuff from them via Mp3Tag some time ago, so, unless I'm missing something else in the code, the huge usage I experienced is with the rotator "blank", so to speak. Which is even more outrageous, from a strict performance (not talking about the code here) point of view ... :confused:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
ItsJustRyan
Posts: 81
Joined: October 25th, 2019, 1:20 am

Re: Reducing CPU usage?

Post by ItsJustRyan »

balala wrote: March 20th, 2023, 3:24 pm Unfortunately the image used into a Rotator meter can't be resized by setting a W and H options on it, as you do with an Image meter. To resize this image, you have to use TransformationMatrix.
Oh I don't intend to resize the rotator images as those are already scaled correctly. I just thought that that was what was being referred to. :D
Yincognito wrote: March 20th, 2023, 3:44 pm For the record, none of my songs have actual cover art images, I deleted all unnecessary stuff from them via Mp3Tag some time ago, so, unless I'm missing something else in the code, the huge usage I experienced is with the rotator "blank", so to speak. Which is even more outrageous, from a strict performance (not talking about the code here) point of view ... :confused:
It's probably because there are "layers" to the vinyl. There's obviously the static stuff like the wood, the base of the arm, the rim and the top layer reflection, but aside from the rotating album cover, there's also the vinyl disk spinning and the arm moves as the song progresses too. (Not to mention all the other stuff, which might be contributing too)
User avatar
Yincognito
Rainmeter Sage
Posts: 7125
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Reducing CPU usage?

Post by Yincognito »

ItsJustRyan wrote: March 20th, 2023, 2:55 pm I might be wrong, but [...] I figured I should put an update of what I've got since it's been more than a week since the last post.
No, you're not, you're right that there are multiple factors (some of which you mentioned now) that influence performance in such a skin, and the effect is cummulative, as you can imagine. That being said, it's also correct that the performance is not (and should not) be acceptable, we just need to find where to "tickle" the code to make it better in that regard.

You did well posting an update, so that the full code can be examined to see what needs to be done to improve it.
ItsJustRyan wrote: March 20th, 2023, 3:51 pmIt's probably because there are "layers" to the vinyl. There's obviously the static stuff like the wood, the base of the arm, the rim and the top layer reflection, but aside from the rotating album cover, there's also the vinyl disk spinning and the arm moves as the song progresses too. (Not to mention all the other stuff, which might be contributing too)
Indeed. Like I said, I didn't have the time to look deeper at what exactly is going on in the skin earlier, now that my other tasks for today are resolved I will take a look and see what comes out of it. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Yincognito
Rainmeter Sage
Posts: 7125
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Reducing CPU usage?

Post by Yincognito »

ItsJustRyan wrote: March 20th, 2023, 2:55 pm But I assume nothing can be done for something like album covers, especially when it's rotating?
It appears something can actually be done. As promised, here is the improved balala's version of one of your earlier skin codes a couple of replies ago (your current skin is way to big to have the patience to go through it line by line), which on my system takes "just" 10% of the CPU with HA turned off, and the mentioned 6% of it with it turned on:
Test_1.0.0.rmskin
and the included code for easy comparison (my player is Winamp, hence the related variable):

Code: Select all

[Variables]
PlayerName=Winamp
PlayerPath=C:\Program Files (x86)\Winamp\Winamp.exe
Update=20
DefaultUpdateDivider=(1000/#Update#)
Deceleration=5
RotX=405
RotY=375
RotW=290
RotH=290

[Rainmeter]
Update=#Update#
DefaultUpdateDivider=#DefaultUpdateDivider#

---Measures NowPlaying---

[GetMusicPlayerStatus]
Measure=NowPlaying
PlayerName=#PlayerName#
PlayerType=STATUS

[GetMusicPlayerState]
Measure=NowPlaying
PlayerName=[GetMusicPlayerStatus]
PlayerType=STATE

[GetSongCover]
Measure=NowPlaying
PlayerName=[GetMusicPlayerStatus]
PlayerType=Cover

[MeasureSongName]
Measure=NowPlaying
PlayerName=[GetMusicPlayerStatus]
PlayerType=Title

[MeasureSongArtist]
Measure=NowPlaying
PlayerName=[GetMusicPlayerStatus]
PlayerType=Artist

[MeasureProgress]
Measure=NowPlaying
PlayerName=[GetMusicPlayerStatus]
PlayerType=PROGRESS

[MeasurePosition]
Measure=NowPlaying
PlayerName=[GetMusicPlayerStatus]
PlayerType=POSITION

[MeasureDuration]
Measure=NowPlaying
PlayerName=[GetMusicPlayerStatus]
PlayerType=DURATION

[mVolume]
Measure=NowPlaying
PlayerName=[GetMusicPlayerStatus]
PlayerType=Volume

---Measure Calc---

[MeasureRotate]
Measure=Calc
Formula=(( GetMusicPlayerState = 1 ) ? (( MeasureRotate % 360 ) + 0.2 ) : MeasureRotate )
MaxValue=360
UpdateDivider=#Deceleration#

[MeasureSinAngle]
Measure=Calc
Formula=SIN(MeasureRotate/360*2*PI)
UpdateDivider=#Deceleration#

[MeasureNegSinAngle]
Measure=Calc
Formula=-(MeasureSinAngle)
UpdateDivider=#Deceleration#

[MeasureCosAngle]
Measure=Calc
Formula=COS(MeasureRotate/360*2*PI)
UpdateDivider=#Deceleration#

[MeasureTXCover]
Measure=Calc
Formula=(#RotY#+(0.5*#RotH#))-MeasureCosAngle*(#RotY#+(0.5*#RotH#))-MeasureSinAngle*(#RotX#+(0.5*#RotW#))
UpdateDivider=#Deceleration#

[MeasureTYCover]
Measure=Calc
Formula=(#RotX#+(0.5*#RotW#))-MeasureNegSinAngle*(#RotY#+(0.5*#RotH#))-MeasureCosAngle*(#RotX#+(0.5*#RotW#))
UpdateDivider=#Deceleration#

[MeasureMinutesTotal]
Measure=Calc
Formula=Trunc(MeasureDuration/60)
RegExpSubstitute=1
Substitute="^(.)$":"0\1"

[MeasureSecondsTotal]
Measure=Calc
Formula=(MeasureDuration % 60)
RegExpSubstitute=1
Substitute="^(.)$":"0\1"

[ProgressSec]
Measure=Calc
Formula=( 550 / ( MeasureSecondsTotal + MeasureMinutesTotal * 60 ))

---Meters---

[Background]
Meter=Image
ImageName=#@#Images\Wood.png
W=1920
H=1080
UpdateDivider=-1

[MeterTrack]
Meter=String
MeasureName=MeasureSongName
X=1920
Y=(1080-35)
W=1670
FontFace=Montserrat SemiBold
FontSize=54.72
AntiAlias=1
StringAlign=RightCenter
Text=%1
FontColor=255,255,255

[MeterArtist]
Meter=String
MeasureName=MeasureSongArtist
X=1920
Y=(1080-85)
FontFace=Montserrat Light
FontSize=30
AntiAlias=1
StringAlign=RightCenter
Text=%1
FontColor=255,255,255

[MeterSongLength]
Meter=String
MeasureName=MeasurePosition
MeasureName2=MeasureDuration
X=(#WorkAreaWidth#-251)
Y=(1080-160-4+23)
FontFace=Montserrat Light
FontSize=(22.8)
AntiAlias=1
StringAlign=Left
Text=%1/%2
FontColor=255,255,255
SolidColor=255,0,0

[CoverRotate]
Meter=Image
MeasureName=GetSongCover
X=#RotX#
Y=#RotY#
W=#RotW#
H=#RotH#
TransformationMatrix=[MeasureCosAngle];[MeasureSinAngle];[MeasureNegSinAngle];[MeasureCosAngle];[MeasureTYCover];[MeasureTXCover]
AntiAlias=1
DynamicVariables=1

[VinylRotate]
Meter=Rotator
MeasureName=MeasureRotate
ImageName=#@#Images\Vinyl.png
X=50
Y=20
W=1000
H=1000
OffsetX=500
OffsetY=500
AntiAlias=1
LeftMouseUpAction=[!CommandMeasure GetMusicPlayerState "PlayPause"]
RightMouseUpAction=["#PlayerPath#"]
MouseScrollUpAction=[!CommandMeasure "MeasureProgress" "SetPosition +[ProgressSec]"]	
MouseScrollDownAction=[!CommandMeasure "MeasureProgress" "SetPosition -[ProgressSec]"]
UpdateDivider=#Deceleration#

[MeterRoundProgBar]
Meter=Roundline
MeasureName=MeasureProgress
Solid=1
AntiAlias=1
StartAngle=(-PI/2)
RotationAngle=(PI*2)
X=(#RotX#+(#RotW#/2))
Y=(#RotY#+(#RotH#/2))
LineLength=430
LineStart=426
LineColor=255,255,255
MouseScrollUpAction=[!CommandMeasure "MeasureProgress" "SetPosition +[ProgressSec]"]	
MouseScrollDownAction=[!CommandMeasure "MeasureProgress" "SetPosition -[ProgressSec]"]
DynamicVariables=1

[CirclesPlayerVol]
Meter=Shape
Shape=Ellipse 45,46,36 | Fill Color 255,255,255,0 | Stroke Color 255,255,255 | StrokeWidth 2
Shape2=Ellipse 45,46,25 | Fill Color 255,255,255,0 | Stroke Color 255,255,255 | StrokeWidth 2
UpdateDivider=-1

[PlayerVol]
Meter=Roundline
MeasureName=mVolume
Solid=1
AntiAlias=1
StartAngle=0
RotationAngle=(PI*2)
X=5
Y=6
W=(2*40)
H=(2*40)
LineLength=(40*0.91)
LineStart=(40*0.55*1.14)
LineColor=255,255,255
RightMouseUpAction=[!CommandMeasure GetMusicPlayerState "TogglePlayer"]
MiddleMouseUpAction=[!CommandMeasure GetMusicPlayerState "TogglePlayer"]
MouseScrollUpAction=[!CommandMeasure GetMusicPlayerState "SetVolume +5"]	
MouseScrollDownAction=[!CommandMeasure GetMusicPlayerState "SetVolume -5"]

[subTextPlayer]
Meter=STRING
MeasureName=mVolume
Text=%1
AntiAlias=1
StringAlign=CenterCenter
FontFace=Montserrat SemiBold
FontSize=20
FontWeight=700
FontColor=255,255,255
X=45
Y=48

[Arm]
Meter=Image
ImageName=#@#Images\Arm.png
X=700
Y=100
W=276
H=600
UpdateDivider=-1
The changes are not extensive, it's more about setting everything to update ONLY when it really needs to. As explained before by others here, big images updated / resized quickly are quite intensive in Rainmeter, so pretty much the only (classic) solution for the vinyl animation (which is the only one in this code you expect to animate smoothly, by the way) is to "decelerate" it via a suited update divider that produces acceptable movement AND performance. I set the related variable to 5 - which means 5 times slower than the skin update rate - and even though the rotation is slower, it's still noticeable and smooth enough if you don't look too closely. Feel free to change it to what you see fit.

The reason why other things in the code don't need smooth animation is because a granularity of less that once per second doesn't make sense for them, since track progress itself and others don't change more often than that - so you can save some CPU impact this way too.

An alternative method to achieve much better performance would be to use Khanhas Webview plugin for Rainmeter to make the animation in a webpage via Javascript or even plain CSS, which can be then placed "inside" your skin via one simple measure. This worked great for my Earth skin and it's almost insensitive to the size of the image as I mentioned earlier, but the process and effort is not as straightforward and simple as coding in an .INI, at least not the first time when you attempt it, not to mention that there are some tricks and things you must do in that case as well.

Other than that, in your current / posted skin, properly handling the cover and vinyl rotations does not seem to be enough to improve performance, I set both their update dividers to -1 and even commented them both and I still have 60% CPU usage without HA. The latter helps, of course, but it's only passing the effort to the quicker GPU instead, not actually "fixing" the issue.
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth