in reply to Perl threads: using yield() and Time::HiRes usleep() in Linux/*nix

I concur. Sleeping already relinquishes the CPU, so yield is redundant and wasteful.

At least that's the theory, but it's supported by the following program using 0% CPU:

use Time::HiRes qw( usleep ); for (;;) { usleep(250000); }

Do you have any reason to believe otherwise?

Update: Screw theory, the following shows usleep does what you want.

use strict; use warnings; use Time::HiRes qw( usleep time ); use threads; { my $i = 0; my $s = time; my $t1 = async { usleep(250000); }; my $t2 = async { ++$i while $i < 50_000_000; }; $_->join() for $t1, $t2; my $e = time; printf("%.0f\n", ($e-$s)*100000); } { my $i = 0; my $s = time; my $t1 = async { }; my $t2 = async { ++$i while $i < 50_000_000; }; $_->join() for $t1, $t2; my $e = time; printf("%.0f\n", ($e-$s)*100000); }

Replies are listed 'Best First'.
Re^2: Perl threads: using yield() and Time::HiRes usleep() in Linux/*nix
by BrowserUk (Patriarch) on May 10, 2009 at 22:00 UTC
    Update: Screw theory, the following shows usleep does what you want.

    Could you explain what you think that code demonstrates?

    C:\test>yield.pl 346500 346021 C:\test>yield.pl 345600 345841 C:\test>yield.pl 346100 345553

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Looks to me like the usleep thread allows the other thread to execute with little to no hindrance. As far as I understand it, that was the OP's question.
        That is correct, sir. It is logic that sleeping (using the OS), should allow for CPU to carry out more work on other threads. The question was whether or not the yield() before or after helps in any way and how yield is implemented in *nix systems with a typical vanilla Perl binary distro.

        To add a bit more context: The program is a scanning and OMR (Optical Mark Recognition aka Bubble Test) corrector. So while the scanner is fetching pages and transmitting images over the USB wire, the OMR lib is processing and decoding. The scanning thread waits for an image queue to be emptied by the OMR thread before fetching for the new image. Threading alone, reduced total processing time to about one third (3 seconds down to a bit over 1 - on average).

        Initially, I just added the millisecond delay so I don't hog the CPU looping on the $image_queue->pending call while the OMR thread clears the queue. I could have used 2 queues and fully sync both threads with a $queue->dequeue on the scanning thread, but the program as whole is really complex so I refrain from adding new things unless absolutely necessary.

        What I was doubtful about, was if adding a yield() before or after the the delay would aid the OS somehow in yielding more CPU time to other threads of the same parent PID. Carrying out different tests it really makes no difference on my single CPU laptop (though the delay alone does help!). I will carry more test on dual-core CPUs and see if it makes any difference. But if not, what is the yield() call there for? It just calls a single no-op? What's the use of single no-op? Does it do anything more interesting on other OSs/Configurations? Can it be compiled to do anything more interesting than a single no-op?
Re^2: Perl threads: using yield() and Time::HiRes usleep() in Linux/*nix
by ait (Hermit) on May 10, 2009 at 20:19 UTC
    Wow, Great example! Thanks for taking the time to write it up!
Re^2: Perl threads: using yield() and Time::HiRes usleep() in Linux/*nix
by Anonymous Monk on May 12, 2011 at 07:43 UTC
    sleep and yield both take the thread off the cpu. If priorities are involved (which they prolly are not in this) then the thread that yields could get put back on immediatly. the sleeping thread will wait until it is woken up at the end of its time. so both should accomplish the goal giving up the cpu, the sleep just wastes a lot processor time. If only one thread is running then you have to wait all that time with the cpu at 0%. yield should give everyone else a chance then come back ASAP. Well it depends on the schedluer of course, but linux is smart