4

What I want to do

I have a computationally intensive OCaml application and I'd like it to run in the background without disturbing normal computer usage. I'd like to present the users with two options:

(1) the application only runs when CPU usage is virtually 0%;

(2) the application only uses "free" processing power (e.g. if other processes add up to 100%, the OCaml application pauses; if other processes are virtually 0%, then there are no restrictions for the OCaml application; if other processes add up to, say, 50% then OCaml will use up to 50%).

Some thoughts

My idea is to check CPU usage at various check points in the code and pause execution if necessary.

In (1), we just check if CPU is below say 2% and, if not, pause until it becomes lower than 2% again.

In (2), things are trickier. Since when no restrictions are present the application always consumes 100% of CPU and checkpoints will be quite frequent, to reduce CPU usage to, say, half, I just have to delay it at every checkpoint by exactly the time it took between check points. If check points are frequent, this would be similar to using 50% CPU, I'd say. For other percentages we can do something similar by suspending for appropriate periods of time. However, this looks very contrived, full of overhead, and above all, I'm not sure it really does what I want. A better alternative could be to invoke Unix.nice n with some appropriate integer at the start of the application. I suppose that setting n=15 would probably be right.

My questions

(Q1) How can I know from within my OCaml application what the CPU usage for the application process is? (I'd like to do this with an OCaml function and not by invoking "ps" or something similar on the command line...)

(Q2) Do you see problems with my idea to achieve (2). Which are the practical differences to changing niceness of process?

(Q3) Do you have any other suggestions for (2)?

Surikator
  • 1,463
  • 9
  • 26

2 Answers2

3

Get your PID then parse the contents of /proc/<PID>/stat to get info about your process and /proc/stat to get global CPU info. They both have a bunch of statistics that you can use to decide when to do work and when to sleep. Do man proc to see the documentation for all the fields (long). Related question with good info: stackoverflow.com/questions/1420426

Setting niceness is easy and reliable. Doing things yourself is much more work but potentially gives you more control. If your actual goal is to just run as a background task, I would go with nice and be done with it.

Community
  • 1
  • 1
Nathan Whitehead
  • 1,942
  • 2
  • 16
  • 19
  • I'm on Mac OS X so I don't have `/proc/stat`. But I could use `ps -v -p [PID] | grep [PID]` and get an easy line to parse. The problem with this approach is that by the time I run `ps`, the system will give me information on the CPU usage of my application **while executing this ps call** and not while doing my calculations which are far more intensive. That's why I wanted some OCaml function to do it for me. I suppose using CPU times and elapsed times (as Norman suggests) should be a better option. Thanks! – Surikator Jul 14 '11 at 01:35
3

Use Caml's Unix library to periodically capture your CPU times and your elapsed times. Your CPU usage is the ratio. Try Unix.gettimeofday and Unix.times. N.B. You'll need to link with the -lunix option.

I too would just run the process under nice and be done with it.

Norman Ramsey
  • 198,648
  • 61
  • 360
  • 533
  • Thanks! Just tried it and it seems to work fine. Ran three instances of a dummy "intensive" application simultaneously, two with nice=20 and another with nice=0, and measured 30%, 30% and 45%, respectively. At the same time it's a bit strange as it should add less than 100%... The Activity Monitor on the MAC tells me 50%, 50% and 80% (note that the monitor figures are doubled because of the dual processor). – Surikator Jul 14 '11 at 02:06