Open JakubFojtik opened 4 years ago
On 3/7/20 2:19 PM, JakubFojtik wrote:
What arguments would cause the maximum execution speed of the |setvcp| command run one after another?
I am using |--noverify --sleep-multiplier 0.1|, but noverify seems to do nothing and the command sometimes needs retrying due to the low multiplier.
Are there other ways to increase speed, like opening a "socket" and reusing it?
The execution time of ddcutil is dominated by sleeps mandated by the DDC/CI protocol. (--sleep-multiplier, as you know, allows you to adjust the length of those sleeps to a lower value that still works for your monitor.) The time spent opening and closing /dev/i2c devices is negligible - see the output of the --stats option.
The current version of branch 0.9.9-dev on github contains a change which eliminates some sleeps entirely and does not appear to cause problems.
You could also run ddcutil using the --bus option, which bypasses display detection, though this is of most value in a multi-monitor environment.
Do be aware that some users have reported problems when multiple setvcp commands issued in rapid succession, i.e. in a script.
I wanted to match the speed of the proprietary I-Menu for AOC monitors, where one can change brightness via a slider real-time. Is that posible with /ddcutil/'s I2C, or are they using their own proprietary protocols?
I-Menu is proprietary Windows software. I have no idea what they're doing.
If you're looking to adjust brightness using a slider, take a look at ddcui. Just beware that what's on github is very much a beta release.
-- Sanford
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/rockowitz/ddcutil/issues/110?email_source=notifications&email_token=ADMGY3QIIEWG7DTCCBRAVRTRGKM3VA5CNFSM4LDSIYT2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4ITKHMDQ, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADMGY3SV7I43HUBFG2GR2O3RGKM3VANCNFSM4LDSIYTQ.
AFAIK, MonitorControl also uses the DDC protocol to do this in real-time on MacOS. Its brightness sliders are smooth. Perhaps it might help.
I’ve had similar smooth experience on Windows, with Twinkle Tray which seems to use node-ddcci as a library to call low level windows API functions such as SetVCPFeature.
Note that I’m sure a 100ms delay is barely noticeable in a slider unless you’re looking for it. But currently with ddcutil 2.0 I see things like:
> time ddcutil -b 1 setvcp 10 100
real 0m3.007s
user 0m0.010s
sys 0m0.067s
So 10ms of user time, 67ms of kernel time, but 3 full seconds of wall clock time -- specifying the bus directly. Not on all monitors thankfully, but even on a faster one there’s at least a lot of variability:
> time ddcutil -b 10 setvcp 10 100
real 0m0.547s
user 0m0.006s
sys 0m0.013s
> time ddcutil -b 10 setvcp 10 100
real 0m0.401s
user 0m0.012s
sys 0m0.006s
> time ddcutil -b 10 setvcp 10 100
real 0m0.167s
user 0m0.008s
sys 0m0.009s
The only other linux implementation I found is based on i2c-tools
, e.g. python-ddci
. That seems to be more error-prone as on the bus that performs slower with ddcutil the ddcli
command returns without actually modifying the brightness 3 out of 4 times. (ddcutil
also fails but much less frequently with “VCP (aka MCCS) version for display is undetected or less than 2.0. Interpretation may not be accurate. Verification failed for feature 10“). Besides it being less reliable, it is blazingly fast:
> time ./ddccli.py -b 1 --brightness 10
real 0m0.028s
user 0m0.019s
sys 0m0.009s
> time ./ddccli.py -b 1 --brightness 100
real 0m0.030s
user 0m0.017s
sys 0m0.013s
> time ./ddccli.py -b 10 --brightness 10
real 0m0.031s
user 0m0.021s
sys 0m0.006s
> time ./ddccli.py -b 10 --brightness 100
real 0m0.038s
user 0m0.027s
sys 0m0.007s
So it’s likely the python-ddci
/i2c-tools
is skipping a lot of possibly mandatory things, but maybe there could be some inspiration taken from there to make things faster?
@Cimbali Is this performance problem new with release 2.0? If so, it might be related to the newly introduced dynamic sleep algorithm, and that needs to be diagnosed.
Before doing anything else, make a copy of $HOME/.cache/ddcutil/dsa so that your accumulated data is not affected by subsequent tests. Next please run sudo ddcutil interrogate and save the output. The output is voluminous, but it avoids a back and forth over lots of little questions. Submit both files as attachments of some sort.
Options --stats and --vstats provide lots of detail about where ddcutil is spending its time and how many I2C retries are required. The latter breaks down the stats by monitor. (If the issue is in the new dynamic sleep algorithm, option --istats dumps internal information as well.)
My guess is that the DDC implementation for the display on bus 1 is marginal, and that the stats will show lots of retries. Assuming the runs on bus 10 are sequential, the decreasing elapsed time would reflect the tuning as dynamic sleep reduces the sleep multiplier.
Try running with option --disable-dynamic-sleep and use option --sleep-multiplier to explicitly set the multiplier factor to be used. Can you find a sleep multiplier value that improves performance? If so, there may be a problem with the dynamic sleep algorithm.
Yes, ddcutil does a lot of checking that python -ddci does not, so it probably works more reliably with your marginal monitor, at the expense of performance. In particular, setvcp automatically performs a getvcp operation to verify that the monitor's value has changed. python-ddcci does not appear to perform that check. Running ddcutil with option --noverify would make its performance more comparable to python-ddcci.
i2c-tools is basically a thin application over driver i2c-dev. ddcutil makes essentially the same system calls to i2c-dev as does i2c-tools.
Regarding Windows, the API functions such as SetVCPFeature are at a much higher level than the I2C interface provided by i2c-dev. If ddcutil were ported to Windows the lowest layers of ddcutil would simply be stripped out. Plus, the Windows video drivers simply have better I2C support. I'm not surprised that DDC performance is better on Windows.
It’s not new with 2.0, it was already there before -- I was just hoping 2.0 would fix it.
I have an applet to control monitor brightness and was hoping to use DDC rather than xrandr --brightness
. In that use case (by scrolling or with a slider), a very large response time is not ideal (3s is not usable, but I’m sure some people could tolerate up to 0.5s).
I understand your new sleep algorithm is dynamically reducing or increasing the sleep multiplier based on previous calls. Is there a way to profile that value? Say on detecting a new screen is connected, run a dozen dummy commands (or brightness -1% / +1%), or until the value has converged?
I agree that 3.0s execution time for individual ddcutil calls makes it unusable for a scrollbar in an app. The real solution is to use the shared library which performs initialization once, but I appreciate that until libddcutil has a python interface that is impractical for most developers. You might want to take a look at how vdu_controls gets around this problem.
Tuning the dynamic sleep-multiplier requires a large number of calls. Doing this automatically when a new monitor is detected would make the initial ddcutil call so slow that it would be perceived as failing. However, your app could have an option to perform a long running profile operation by making a large number of getvcp calls (and hiding the output) on user request.
@Cimbali, I have added an experimental option to branch 2.0.2-dev, -skip-ddc-checks. It is valid only if the display is selected by its bus number (option --bus) and only for commands getvcp and setvcp. Because it is experimental, it is listed only by option --hh, not --help.
If specified, ddcutil initialization does not check if DDC communication is working, and does not check that the monitor reports unsupported features as per the DDC/CI spec, For any "reasonable" monitor, these checks should never fail. The downside is that either of these things is not true, it's unclear how the getvcp or setvcp command will fail.
Also, to make the slider more responsive and if you have not already done so, consider using option --noverify on the setvcp calls, and only call getvcp once after the slider operation is complete to get the final value.
What arguments would cause the maximum execution speed of the
setvcp
command run one after another?I am using
--noverify --sleep-multiplier 0.1
, but the command sometimes needs retrying due to the low multiplier.Are there other ways to increase speed, like opening a "socket" and reusing it?
I wanted to match the speed of the proprietary I-Menu for AOC monitors, where one can change brightness via a slider real-time. Is that posible with ddcutil's I2C, or are they using their own proprietary protocols?