mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
28.04k stars 2.88k forks source link

Implement configuration of mpv's default process priority under Linux #3399

Closed v-fox closed 7 years ago

v-fox commented 8 years ago

It seems that mpv supports configuration of default priority under Windows but not under Linux. Linux has two-tier system to do so: schedulers and priorities for them. The default is SCHED_OTHER which takes "niceness" level (-20/20), and three others are for realtime: SCHED_FIFO (this is what JACK uses) and SCHED_RR that both take 1-99 priority number and SCHED_DEADLINE which has complex configuration but, supposedly, is the best of all. There are also SCHED_BATCH and SCHED_IDLE for high-intensity and low-intensity background operations. It seems you can set them separately for each thread. See man chrt and man sched

In my tests for highly-demanding mpv config SCHED_OTHER with niceseness -10 or "lower" works the best and gives no frame drops if CPU frequency-scaling is disabled (with frequency-scaling it can "drop by vo" a frame or two in 5 minutes). It's also the only setting I can use mpv in >8-years old laptop. However, I didn't try high realtime priorities to avoid interference with jack server.

It would be great to have means to set those settings without hacks with nice and chrt. Also, maybe if you would fiddle with those per each thread of mpv, you could find better universal defaults that would guarantee needed CPU time for mpv's time-critical tasks.

ghost commented 8 years ago

I don't think that mpv should change these. I know there's some code for Windows, but even that is only there because it was inherited from mplayer, and rather questionable. (I've never seen anyone using it.)

You could probably implement them as Lua script.

WhitePeter commented 8 years ago

Hi there, just signed up to give my 2 cents to this.

I also do not think this should be done inside the application. My guess why there is code for Windows handling this is that Windows has rather terrible means to start applications with those properties set.

To do this in Linux is rather easy. There is schedtool which can set all those schedulers and priorities. Once one has found their desired settings put them in a shell alias, like: alias mpv="schedtool -n -10 -e mpv" in your case @v-fox.

And I don't consider this hackish. It is the proper way of doing things in a unixoid OS: "Do one thing and do it well". MPV is a media player and should not be concerned too much about the OS it is running on. That is what tools like nice, chrt and schedtool and whatnot are there for in the first place. They do that one thing, do it well and fit in nicely in the environment. Also, the logical conclusion of your reasoning would be that all programs had to have code for this. That adds complexity which in turn decreases robustness and maintainablilty, definitely not the UNIX way. BTW, negative nice levels are not to be set by unprivileged users. And running mpv as root is not such a good idea, IMO. If you get dropped frames without setting negative nice levels that can only mean, there are other applications getting in the way, so make those behave nice. The name of that tool is no coincidence. It means, that programs started with a higher nice level are nicer to other processes by yielding more often, or rather by being forced to yield by the scheduler.

And last but not least, the odd dropped frame in five minutes is acceptable, IMHO. I am running mpv on Debian and a Phenom II x4 965, so I'd say that is not slow for mpv. But even I see the dropped frames counter increase occasionally. Not that I would notice if I didn't look at the counter, though. So, unless you really see playback degradation without looking at the counter, I would not bother.

v-fox commented 8 years ago

I would almost agree with you if mpv's wouldn't be a high-load high-interactivity multimedia application which asks inadequately low default priority for its job which becomes noticeable with non-excessive CPU&GPU power, under load or on older systems.

And I really would like a GNU/Linux distribution with desktop orientation that would have proper process priorities for everything, from system deamons to console emulators. And not just on process level, but on level of threads and CPU core affinity. Sadly, there is no commercial interest in this and USA-derived software laws are interfering with its non-commercial proliferation. Although, Linux'es responsiveness under load is already second to none.

Anyway, even if you would consider manual set ups of external mpv launchers as a norm, it does not address the idea of setting appropriate priorities for different thread inside mpv (it has like 26 on my system) and informing kernel about its time-critical tasks. Hopefully, JACK automatically sets up SCHED_FIFO and slightly-lesser-than-its-own priority for JACK output of the mpv (see chrt -a --pid $(pidof mpv)).

BTW, negative nice levels are not to be set by unprivileged users. And running mpv as root is not such a good idea, IMO.

/etc/security/limits.conf

pulse - rtprio 88
pulse - memlock 102400
pulse - nice -15
@users soft rtprio 89
@users hard rtprio unlimited
@users soft memlock 1024000
@users hard memlock unlimited
@users - nice -20

Or, maybe, adjust /etc/systemd/user.conf Otherwise, what's the point of having an option for "privileged" processes on a desktop system if they don't even exist ?

If you get dropped frames without setting negative nice levels that can only mean, there are other applications getting in the way, so make those behave nice.

What's easier: setting lower priority for all system processes or setting higher one for the prioritized one ? It's especially important for user's processes on desktop because pretty much all of them are interactive.

But that's more of the frequency scaling issue: kernel limits mpv instead of increasing frequency on the core that doesn't have enough CPU time for some of mpv's threads or limiting something else. With higher priority of mpv it just limits something else but it's still not 100% drop-free with scaling.

And last but not least, the odd dropped frame in five minutes is acceptable, IMHO. I am running mpv on Debian and a Phenom II x4 965, so I'd say that is not slow for mpv. But even I see the dropped frames counter increase occasionally. Not that I would notice if I didn't look at the counter, though. So, unless you really see playback degradation without looking at the counter, I would not bother.

Yeah, and it's probably mpv's interpolation fault (I wish there was motion-interpolation on GPU support and my system could handle it, now it can only do <720p with no drops on most videos but with pretty much full CPU load but this stuff is magnificent) which is always finicky and goes from unnoticeable to blurry. However, after zero drops under any kind of load but without frequency scaling and with niceness -10, the fact of occasional drop, the gall of mpv to drop on semi-idle system is more irritating than the drop itself.

Ah, and there is also ionice with its I/O priority which may be useful with high-bitrate media and under I/O load, such as while copying files, doing backups or downloading videos for future wathing. But it's said that it's already set automatically to an adequate value (0-7) with io_priority = (cpu_nice + 20) / 5 formula.

WhitePeter commented 8 years ago

I would almost agree with you if mpv's wouldn't be a high-load high-interactivity multimedia application which asks inadequately low default priority for its job which becomes noticeable with non-excessive CPU&GPU power, under load or on older systems.

What do you mean by inadequately low priority? As far as I can see it is the highest possible on a default Linux, SCHED_OTHER, nice 0. It is the same for everything, unless eplicitly set otherwise, provided permission is granted.

And I really would like a GNU/Linux distribution with desktop orientation that would have proper process priorities for everything, from system deamons to console emulators.

I think that would be the wrong place to fix it. Also, there is only so much that can be done. The right place for fixing things like this is the kernel, IMHO. Debian, for example, has a kernel that is geared more towards servers. There are some config variables that can be tweaked more in the direction of interactive use, can't remember those ATM, stopped bothering a long time ago.

Anyway, even if you would consider manual set ups of external mpv launchers as a norm, it does not address the idea of setting appropriate priorities for different thread inside mpv (it has like 26 on my system) and informing kernel about its time-critical tasks.

The way I understand it, the threads inherit priority and nice level from the parent. I cannot see the point of setting different nice levels and/or priorities for different threads here. The lower priority threads would be stalled eventually making the higher priority threads wait for them, anyway. I don't see how complete independence between threads would be possible. But then, I am not a developer.

/etc/security/limits.conf

Ah, thanks for reminding me. But you do run the risk of stalling everything else if mpv decides to go berserk and hog all CPU resources. That's why you are not allowed to set aggressive nice levels and priorities as an ordinary user in the first place. You can hang your system for good, this way. Even Windows warns you to this effect. Linux is just silent about it, because root is assumed to know what they are doing. But there is plenty warning all over the web and in the docs.

Or, maybe, adjust /etc/systemd/user.conf

Ah, since you mentioned systemd. Maybe think about another init system or look into the configs of systemd. Since it uses cgroups by default, there is a performance penalty right there for you. Note, this is not a rant about systemd! It is a great piece of kit, but some of the features come at a price. Maybe that is worth thinking about on an 8 year old laptop.

Otherwise, what's the point of having an option for "privileged" processes on a desktop system if they don't even exist ?

That is not what "privileged" means. What you mean is prioritized. If you think you must set lower nice levels than 0, nobody is stopping you. But you do need the privilege to do so, only root may edit limits.conf. ;)

What's easier: setting lower priority for all system processes or setting higher one for the prioritized one ?

Not all, just the ones getting in the way. A real Desktop system should not have to many system processes and daemons to begin with. It is not a server. But I agree, that many distros might go overboard and lose sight of what a desktop is about. But, as I said, I also think the kernel could be improved in this respect. Question is, how likely that is. ;)

But that's more of the frequency scaling issue ...

That quite clearly is something that needs to be fixed at the kernel level. Or you just need to configure your frequency scaler correctly. Especially on a laptop the default might be geared towards energy saving instead of responsiveness. Check which scaling governor is in use and how it is configured: cat /sys/devices/system/cpu/cpu?*/cpufreq/scaling_governor ls /sys/devices/system/cpu/cpufreq/

Yeah, and it's probably mpv's interpolation fault ...

I don't know. Maybe it is due to drivers in Linux. I have a Radeon 5770 using the Mesa drivers that come with Debian 8. In my book that card should be plenty powerful for the task of interpolation, yet it still results in choppy playback with more aggressive opengl-hq settings plus video-sync=display-resample and interpolation on high resolution material, also >720p mostly. For the time being I have made a profile with my smoothmotion settings but leave it disabled by default. And just because there are no dropped frames with interpolation does not mean the playback is not choppy. It is just another value to look for in the status line: AV: 00:00:01 / 00:05:00 (0%) A-V: -0.017 DS: 2.545/0 Cache: 10s+30MB As far as I have grasped it, DS: .../>0 practically means the same as dropped frames without display-resample would. Those are late frames which show as stutter/choppyness.

(Edit: minor spelling and orthographical corrections)

qmega commented 8 years ago

For people looking to prioritize desktop responsiveness, take a look at the Brain Fuck Scheduler from the Linux-ck patchset. It's good at keeping interactive programs responsive when the system is under load in general, but it also provides an extra scheduling class SCHED_ISO which is basically designed for cases like video players. It gives low latency and scheduling priority over normal programs, but can't lock up the whole system and doesn't require root privileges. I run mpv with SCHED_ISO using schedtool with a wrapper script. I'm not at my computer now to give numbers, but IIRC it lowers my vsync-jitter a bit even when the system is idle.

On Aug 8, 2016, at 09:19, WhitePeter notifications@github.com wrote:

I would almost agree with you if mpv's wouldn't be a high-load high-interactivity multimedia application which asks inadequately low default priority for its job which becomes noticeable with non-excessive CPU&GPU power, under load or on older systems.

What do you mean by inadequately low priority? As far as I can see it is the highest possible on a default Linux, SCHED_OTHER, nice 0. It is the same for everything, unless eplicitly set otherwise, provided permission is granted.

And I really would like a GNU/Linux distribution with desktop orientation that would have proper process priorities for everything, from system deamons to console emulators.

I think that would be the wrong place to fix it. Also, there is only so much that can be done. The right place for fixing things like this is the kernel, IMHO. Debian, for example, has a kernel that is geared more towards servers. There are some config variables that can be tweaked more in the direction of interactive use, can't remember those ATM, stopped bothering a long time ago.

Anyway, even if you would consider manual set ups of external mpv launchers as a norm, it does not address the idea of setting appropriate priorities for different thread inside mpv (it has like 26 on my system) and informing kernel about its time-critical tasks.

The way I understand it, the threads inherit priority and nice level from the parent. I cannot see the point of setting different nice levels and/or priorities for different threads here. The lower priority threads would be stalled eventually making the higher priority threads wait for them, anyway. I don't see how complete independence between threads would be possible. But then, I am not a developer.

/etc/security/limits.conf

Ah, thanks for reminding me. But you do run the risk of stalling everything else if mpv decides to go berserk and hog all CPU resources. That's why you are not allowed to set aggressive nice levels and priorities as an ordinary user in the first place. You can hang your system for good, this way. Even Windows warns you to this effect. Linux is just silent about it, because root is assumed to what they are doing. But there is plenty warning all over the web and in the docs.

Or, maybe, adjust /etc/systemd/user.conf

Ah, since you mentioned systemd. Maybe think about another init systems or look into the configs of systemd. Since it uses cgroups by default, there is a performance penalty right there for you. Note, this is not a rant about systemd! It is a great piece of kit, but some of the features come at a price. Maybe that is worth thinking about on an 8 year old laptop.

Otherwise, what's the point of having an option for "privileged" processes on a desktop system if they don't even exist ?

That is not what "privileged" means. What you mean is prioritized. If you think you must set lower nice levels than 0, nobody is stopping you. But you do need the privilege to do so, only root may edit limits.conf. ;)

What's easier: setting lower priority for all system processes or setting higher one for the prioritized one ?

Not all, just the ones getting in the way. A real Desktop system should not have to many system processes and daemons to begin with. It is not a server. But I agree, that many distros might go overboard and lose sight of what a desktop is about. But, as I said, I also thin the kernel could be improved in this respect. Question is, how likely that is. ;)

But that's more of the frequency scaling issue ...

That quite clearly is something that needs to be fixed at the kernel level. Or you just need to configure your frequency scaler correctly. Especially on a laptop the default might be geared towards energy saving instead of responsiveness. Check which scaling governor is in use and how it is configured: cat /sys/devices/system/cpu/cpu?*/cpufreq/scaling_governor ls /sys/devices/system/cpu/cpufreq/

Yeah, and it's probably mpv's interpolation fault ...

I don't know. Maybe it is due to drivers in Linux. I have a Radeon 5770 using the Mesa drivers that come with Debian 8. In my book that card should be plenty powerful for the task of interpolation, yet it still results in choppy playback with more aggressive opengl-hq settings plus video-sync=display-resample and interpolation on high resolution material, also >720p mostly. For the time being I have made a profile with my smoothmotion settings but leave it disabled by default. And just because there are no dropped frames with interpolation does not mean the playback is not choppy. It is just another value to look for in the status line: AV: 00:00:01 / 00:05:00 (0%) A-V: -0.017 DS: 2.545/0 Cache: 10s+30MB As far as I have grasped it, DS: .../>0 practically means the same as dropped frames without display-resample would means. Those are late frames which show as stutter/choppyness.

― You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

ghost commented 8 years ago

In theory it would actually be a good idea to tell the kernel about high priority threads (i.e. the audio and video renderer threads), but then I still don't see any proof that changing the scheduling class for those would lead to significant improvements on common setups.

mia-0 commented 7 years ago

Problems with interactivity and mpv playback judder when the system is under load are usually a result of a bad kernel configuration, and it doesn’t take the -ck patchset to fix this.

qmega commented 7 years ago

Out of curiosity, could you give any examples of the kernel configuration you're thinking of?

I tried again and with no load, I can't see a difference in vsync-jitter, so maybe I just made that up. But with heavy load (running an optipng on each core, for example) and a CPU-intensive job for mpv (2880x1620 60fps HEVC decoding) I get framedrops and visible stutter without SCHED_ISO and perfectly smooth playback with it. Negative niceness helps a little, but it still visibly lags, plus that requires root. I guess it's a bit contrived because if I did a batch job like that for real I'd run it with nice, but I do think it demonstrates the effectiveness of SCHED_ISO.

As an interesting side-note, I noticed that vsync-jitter actually goes to 0.000 sometimes with SCHED_ISO under load, while with no load it's usually 0.001 but I've never seen it go to 0.000. I guess this is because of CPU frequency scaling?

haasn commented 7 years ago

FWIW, watching 4K HEVC videos under heavy load is basically impossible for me even with nice -n -10. I'd try out the -ck patchset if it wasn't for the fact that it's stuck on a 5-version old kernel. (at least on gentoo)

v-fox commented 7 years ago

FWIW, watching 4K HEVC videos under heavy load is basically impossible for me even with nice -n -10.

Try disabling CONFIG_SCHED_AUTOGROUP and CGROUP_SCHED in kernel config. Simpler done via sysctl kernel.sched_autogroup_enabled=0. It seems that autogrouping is dividing all processes into equally-prioritized groups based solely on login sessions.

Out of curiosity, could you give any examples of the kernel configuration you're thinking of?

Well, currently I'm using this exact configuration: https://build.opensuse.org/package/view_file/home:X0F:HSF:Kernel/kernel-HSF/config.HSF?expand=1

I tried again and with no load, I can't see a difference in vsync-jitter, so maybe I just made that up.

I'm not use that vsync-jitter is a perfect indicator for frame drops (I rarely get it lower than 0.100, usually 0.130-0.160). For me situation is always worse at low load because then kernel sets CPU frequency to the lowest and sometimes doesn't react fast enough in raising it.

What is surprising for me is that setting SCHED_OTHER with mere -10 for mpv gains better results than realtime RR and FIFO on max (maybe its own high-latency tasks interfere with low-latency tasks ?). I assume that, ideally, applications should be coded to explicitly and correctly use SCHED_DEADLINE and everything else is guesswork. Especially with power-saving considerations.

Problems with interactivity and mpv playback judder when the system is under load are usually a result of a bad kernel configuration, and it doesn’t take the -ck patchset to fix this.

I'm afraid there is no miracle kernel technology that would allow kernel to know which threads and processes are realtime/interactive/latency-demanding and which are not so much, unless they say so for themselves. Well, I guess some kind of global profiling is possible but no one is going to do that any time soon.

What do you mean by inadequately low priority? As far as I can see it is the highest possible on a default Linux, SCHED_OTHER, nice 0. It is the same for everything, unless eplicitly set otherwise, provided permission is granted. I think that would be the wrong place to fix it. Also, there is only so much that can be done. The right place for fixing things like this is the kernel, IMHO.

Well, I think that defaults are quite atrocious for desktop in all Linux distributions, unfortunately. And after the death of KDE3.5 and Gnome2, Linux desktop is quite atrocious in its entirety. Superb balancing abilities of the kernel compensate for that but you can only do so much on kernel-side.

Not all, just the ones getting in the way. A real Desktop system should not have to many system processes and daemons to begin with. It is not a server. But I agree, that many distros might go overboard and lose sight of what a desktop is about. But, as I said, I also think the kernel could be improved in this respect. Question is, how likely that is. ;)

On contrary, servers are usually task-centric, highly-optimized and limited in software. But desktops now are swarmed by weird auto-spawning crap. I don't think kernel can do any more on that other than profiling all processes all the time to build and adjust some kind of statistic-based autopriority map for every single function of every single executable. It would be nicer if software itself would provide it with the correct info.

That quite clearly is something that needs to be fixed at the kernel level. Or you just need to configure your frequency scaler correctly. Especially on a laptop the default might be geared towards energy saving instead of responsiveness. Check which scaling governor is in use and how it is configured:

Until recently there was only 1 sane choice: ondemand. And now there is schedutil which aims to be its saner replacement that would account for all performance data gathered by kernel. They both still just not responsive enough. It may be so that they will never be such because otherwise they themselves would use too much resources.

I don't know. Maybe it is due to drivers in Linux. I have a Radeon 5770 using the Mesa drivers that come with Debian 8. In my book that card should be plenty powerful for the task of interpolation, yet it still results in choppy playback with more aggressive opengl-hq settings plus video-sync=display-resample and interpolation on high resolution material, also >720p mostly. For the time being I have made a profile with my smoothmotion settings but leave it disabled by default. And just because there are no dropped frames with interpolation does not mean the playback is not choppy. It is just another value to look for in the status line: AV: 00:00:01 / 00:05:00 (0%) A-V: -0.017 DS: 2.545/0 Cache: 10s+30MB As far as I have grasped it, DS: .../>0 practically means the same as dropped frames without display-resample would. Those are late frames which show as stutter/choppyness.

Yeah, mpv's interpolation is so wonky for its results that I shouldn't probably use it. If it would do motion-based interpolation on the GPU, you could forgive its demands but the damn thing blurring instead of smoothing unlike mvtools -_-

qmega commented 7 years ago

I'd try out the -ck patchset if it wasn't for the fact that it's stuck on a 5-version old kernel. (at least on gentoo)

The latest -ck applies to the latest kernel. The AUR package is up to date. Looks like the gentoo package has no maintainer. If you're building your kernel anyway it shouldn't be too hard to do the patches yourself to try it out. The most important config is the scheduler: CONFIG_SCHED_MUQSS=y. That should get you a working SCHED_ISO. Other maybe-relevant settings from -ck with the caveat that I have no idea what I'm talking about: CONFIG_SMT_NICE, CONFIG_HZ_100, CONFIG_WBT.

Interesting to note is that CONFIG_SCHED_AUTOGROUP which @v-fox recommended disabling is one of the things that is forcibly disabled by CONFIG_SCHED_MUQSS.

mia-0 commented 7 years ago

BTW, on modern Intel-based laptops (Haswell and newer), you can pretty much just set the frequency scaling governor to performance. Doesn’t reduce energy efficiency in my experience, as these processors can power down and wake up pretty quickly. Nowadays I get crazy battery life from my laptop anyway, almost twice as much as the manufacturer rating for the type of battery that it came with (even after I replaced the display with a more power hungry one), and two hours more than what I got with older kernels. Something must have improved quite dramatically in that area.

haasn commented 7 years ago

Try disabling CONFIG_SCHED_AUTOGROUP and CGROUP_SCHED in kernel config. Simpler done via sysctl kernel.sched_autogroup_enabled=0. It seems that autogrouping is dividing all processes into equally-prioritized groups based solely on login sessions.

I tried disabling autogrouping via the sysctl (didn't reboot), but it didn't help in the slightest. CGROUP_SCHED is still on however.

mia-0 commented 7 years ago

I really don’t think OS process scheduling is mpv’s problem, and I don’t believe the Windows option has a good reason to exist either.