Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: TThread vs CPU usage?

  1. #1

    TThread vs CPU usage?

    What is the best way to keep the cpu usage of an TThread descendant class low?

    I used an sleep(50) to get from 80% cpu usage to 8% cpu usage.

    But i am afraid sleep is dependend on the speed of the cpu. So depending of the cpu speed the value of 50 should be higer or lower?

    Are there other better ways to do this?

    I also thought of using application.processmessages but that one is not available form within my TThread based class.

    Thanks for your answers in advance.
    http://3das.noeska.com - create adventure games without programming

  2. #2

    TThread vs CPU usage?

    Do you mean for a game loop? If so, I think the best is to define the FPS you need, time the work done in inside the loop, and sleep the amount of time you are not using in the frame.

    OTOH, I have found that Sleep( 8 ) works ok on Windows, in several machines.

  3. #3

    TThread vs CPU usage?

    What does your thread do?

    Sleep uses milliseconds so it's not CPU frequency dependant. Application.Processmessages should be accesible trough the 'forms' unit(as Application is a global variable in VCL programs).

    If your thread does a lot of waiting or synchronizing then you should probably use a mutex instead. If it does timeslice updating then sleep is the most optimal solution
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  4. #4

    TThread vs CPU usage?

    I use it to stream a mp3 file to openal.
    If i set sleep to high sound is interupted by silence. If i set it to low the cpu usage goes up. The mp3 decode part might take longer or shorter dependend on the cpu. So on a slow pc sleep(50) may also take to long.

    see also: http://www.pascalgamedevelopment.com...67557955#41863
    http://3das.noeska.com - create adventure games without programming

  5. #5

    TThread vs CPU usage?

    As the first thing I would remove your critical section handling. It makes no sense at all. Make it look like this:

    [pascal]
    while not terminated do
    begin
    updatebuffer;
    sleep(50); //TODO: are there better ways to do this?
    end;[/pascal]

    I can't think of anything else. You could calculate the time you would need between updates by dividing your bitrate with your buffersize, but I don't think that'll make it better.

    8% also sounds like a fine percentage to me
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  6. #6

    TThread vs CPU usage?

    sleep pauses the tread for some time, i think there is no bether way

    (i heard that waitforsingleobject and waitformultipleobjects uses sleep internaly, but im not sure, it can be another option)
    From brazil (:

    Pascal pownz!

  7. #7

    TThread vs CPU usage?

    I suggest to make two buffers. One to play from and other to decode to.
    Code which plays the buffers will set hBufferPlayedEvent by calling SetEvent(hBufferPlayedEvent) when it ends with one buffer and switches to other (just swapping pointers). Decoding thread will get this event and will start decoding to buffer which was just played. Backbuffer technique.

    You decoding threads's code will be something like this:
    Code:
    while not terminated do 
      begin 
        updatebuffer; 
        WaitforSingleObject(hBufferPlayedEvent, INFINITE); 
      end;
    Actually it's better to use WaitforMultipleObjects() to correctly exit the loop when program terminates, but it's "premature optimizations" for now.

  8. #8

    TThread vs CPU usage?

    Mirage is correct.

    [pascal]const
    P2D_OGG_BUFSIZE = 1024*8;
    P2D_THREAD_DELAY = 5; // milliseconds

    procedure TOggPlayer.Update;
    var
    pos : DWORD;
    size: DWORD;
    buf : pchar;
    pbuf: pchar;
    sec : Integer;
    ret : Integer;
    begin
    if FDone then Exit;

    if FPaused then Exit;

    FDSBuffer.GetCurrentPosition(@pos, nil);

    //nCurSection = pos<BUFSIZE?0:1;
    if pos<P2D_OGG_BUFSIZE then
    FCurSection := 0
    else
    FCurSection := 1;

    // section changed?
    if (FCurSection <> FLastSection) then
    begin
    if (FDone = True) and (FLoop = False) then
    begin
    Stop();
    end;

    // gotta use this trick 'cause otherwise there wont be played all bits
    if (FAlmostDone = True) and (FLoop = False) then
    begin
    FDone := True;
    Stop();
    end;

    size := P2D_OGG_BUFSIZE;

    // fill the section we just left
    buf := nil;
    FDSBuffer.Lock(FLastSection*P2D_OGG_BUFSIZE, size, @buf, @size, nil, nil, 0 );

    pos := 0;
    sec := 0;
    ret := 1;

    while((ret > 0) and (pos<size> 0) and (pos<size)) do
    begin
    pbuf := buf + pos;
    ret := ov_read(FVorbisFile, pbuf^, size-pos, 0, 2, 1, @sec);
    inc(pos, ret);
    end;
    end
    else if ((ret = 0) and (FLoop = False)) then
    begin
    // not looping so fill the rest with 0
    while(pos<size) do
    begin
    pbuf := buf + pos;
    pbuf^ := #0;
    inc(pos);
    end;

    // and say that after the current section no other sectin follows
    FAlmostDone := True;
    end;

    FDSBuffer.Unlock( buf, size, nil, 0);

    FLastSection := FCurSection;

    end;
    end;

    procedure TOggAudioThread.Execute;
    begin
    repeat
    CriticalSection_Enter;
    if Assigned(Audio) then
    begin
    Audio.Update;
    end;
    Sleep(P2D_THREAD_DELAY);
    CriticalSection_Leave;
    until Terminated;
    end;[/pascal]
    Jarrod Davis
    Technical Director @ Piradyne Games

  9. #9

    TThread vs CPU usage?

    Mirage, the problem is that there's no callback or anything which is called when the buffer has been finished. You have to poll it yourself. Calls to the OpenAL API are nonblocking to my knowledge.

    Doublebuffering will help against studdering and silences between updates, but you still have to do the polling with regular timesteps
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  10. #10

    TThread vs CPU usage?

    i already use two buffers. whilst one is playing the other one is filled. with unque and que buffer the order of the buffers is altered.

    But as jrsoftware says i have to poll the bufferstate for the source. there is no event for that in openal.

    But as i found out sleep(1) works aswell. Just do not use sleep(0) as that locks up your pc.

    @pyrogine you also use sleep. also i do not see you using an event as pointed out by mirage.
    http://3das.noeska.com - create adventure games without programming

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •