1

I have this perl script and I discovered the pv command and decided to use it to get some feedback into what is going on with the randomness in terms of throughput. After a few tests1 I decided to throttle the command, like so:

perl_commands < /dev/urandom | pv -L 512k | tr -cd SET

5.5MiB 0:00:11 [ 529kiB/s] [                    <=>                             ]

I suspend to ram using systemctl suspend(Archbang). When I resume, the command still runs and includes the elapsed time since suspend in its dialog but it looks as if the limit I set is no longer enforced, throughput is 2-3MiB/s and CPU is higher - like without a limit. After some time, this subsides and I can see that the limit is still enforced.

For example, if I run the command for only a few seconds it'll take seconds for the throughput to come back to its set limit. On the other hand, generating 815Mb of data during an hour, then suspending for 30 mins, it then takes about 5 mins for the command to return to the limit I had set - and CPU usage is like with no throttling during that time.

So it is not that the limit isn't enforced, it's rather that coming out of suspend to ram seems to impact the throughput in this context. Why and can this behavior be changed?


1. The command uses one CPU core when not throttled. With a limit of 512KiB\s, CPU usage is about 10-15% or less. It takes about 2gb of randomness(and some time) to fill my 80x40 terminal window (depending on SET).

0

2 Answers 2

3

pv doesn't know about the system power states. All it sees is that the clock changed by a very large amount at some point.

My guess is that pv doesn't care if the amount of time between two clock readouts suddenly gets large and just calculates the throughput based on the time interval. Since the interval is very large, it appears that the throughput is very low.

The throughput calculation is averaged over a number of clock reads (about 5min in your observations). As long as the interval considered includes the time spent in suspension, the calculated throughput value will be very low. Once the interval again consists only of awake time, the throughput will be back to what is expected.

For example, suppose that you suspended for 5 minutes. Then just after resuming, pv calculates that 500kB were transferred in the last 5min, meaning a throughput of only about 1.7kB/s. That's way below the 500kB threshold so pv transfers more data for a while to compensate. Eventually the throughput calculation will stabilize again.

Suspending the system is not like suspending the pv process. Suspending the system is transparent for programs. Suspending the process sends it a SIGCONT signal when it wakes up. pv has a signal handler for SIGCONT which causes it to more or less subtract the time it spent suspended (I haven't check what exactly it does if it was suspended with an uncatchable SIGSTOP signal, but it shouldn't cause too big a perturbation, unlike system suspension).

3
  • Indeed as you explained it stabilizes after a predictable time: in my case 30 mins... 1800*.0512=922MiB not accounted for during suspend. So even considering max throughput at 3MiB/s with no limit, let's say 2,5 if it were beyond the current 512KiB/s, it computes to 5-6 minutes. I am really surprised that suspending the system doesn't suspend the processes. That was really instructive. Thank you!
    – user44370
    Commented Jun 4, 2014 at 3:05
  • I don't know if you'll find it suprising, but after stopping the job, leaving it there, then back to fg I get the exact same scenario...
    – user44370
    Commented Jun 4, 2014 at 7:43
  • @illuminÉ Huh, weird. I haven't tested it, I glanced at the code and I found a SIGCONT handler that seemed to do what you expect. Treating suspension time as active makes sense in the majority of use cases for pv, I guess, where the limit corresponds to some external thing (typically network bandwidth) that doesn't care whether pv or your whole computer gets suspended. Commented Jun 4, 2014 at 8:18
0

In a scenario like this where making sure that we remain below the limit is the most important factor, you may try this alternative - cstream(with throughput summary every 2 mins here):

cstream -t -512k -T 120

The throughput option, which allows for a negative number, seems designed for this situation:

-t num     Limit the throughput of the data stream to num bytes/second.
           Limiting is done at the input side, you can rely on cstream not
           accepting more than this rate. If the number you give is posi-
           tive, cstream accumulates errors and tries to keep the overall
           rate at the specified value, for the whole session. If you give
           a negative number, it is an upper limit for each read/write
           system call pair. In other words: the negative number will
           never exceed that limit, the positive number will exceed it to
           make good for previous underutilization.

Works with suspending both process or system.

You must log in to answer this question.