History

Use WelsMultipleEventsWaitSingleBlocking with a master event for waiting on finished threads

This allows using the same codepath for both unix and windows for distributing new slices to code to threads. This also improves the performance on unix - instead of waiting for all the current threads to finish their current slice before handing out a new slice to each of them (where the threads that finish first will just wait instead of immediately getting a new slice to work on), we now use the same logic as on windows. In one setup, it improves the performance of encoding from ~920 fps to ~950 fps, and in another setup it goes from ~390 fps to ~660 fps. (These tests were done with the SM_ROWMB_SLICE mode, which heavily exercises the code for distributing new slices to the worker threads.) The extra WelsEventSignal call on windows where it isn't strictly necessary doesn't incur any measurable slowdown, so it is kept without any extra ifdefs to keep the code more readable and unified.

Martin Storsjö committed 12 years ago

Commit 801da261 parent d0a81353 files · +18 −30Browse files

Showing the changes to codec/encoder/core/src/encoder_ext.cpp (1 of 3 files). Show all

Unified · Split

codec/encoder/core/src/encoder_ext.cpp+4−27
@@ -3225,7 +3225,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo * pFbi, const SSou · 3224 unmodified lines
32253225 return ENC_RETURN_UNEXPECTED;
32263226 }
32273227
3228− WelsMultipleEventsWaitAllBlocking (iSliceCount, &pCtx->pSliceThreading->pSliceCodedEvent[0]);
3228+ WelsMultipleEventsWaitAllBlocking (iSliceCount, &pCtx->pSliceThreading->pSliceCodedEvent[0], &pCtx->pSliceThreading->pSliceCodedMasterEvent);
32293229
32303230
32313231 // all slices are finished coding here
@@ -3266,12 +3266,12 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo * pFbi, const SSou · 34 unmodified lines
32663266 while (1) {
32673267 if (iIndexOfSliceToBeCoded >= iSliceCount && iNumThreadsRunning <= 0)
32683268 break;
3269−#ifdef _WIN32
32703269 WELS_THREAD_ERROR_CODE lwait = 0;
32713270 int32_t iEventId = -1;
32723271
32733272 lwait = WelsMultipleEventsWaitSingleBlocking (iNumThreadsScheduled,
3274− &pCtx->pSliceThreading->pSliceCodedEvent[0]);
3273+ &pCtx->pSliceThreading->pSliceCodedEvent[0],
3274+ &pCtx->pSliceThreading->pSliceCodedMasterEvent);
32753275 iEventId = (int32_t) (lwait - WELS_THREAD_ERROR_WAIT_OBJECT_0);
32763276 if (iEventId >= 0 && iEventId < iNumThreadsScheduled) {
32773277 if (iIndexOfSliceToBeCoded < iSliceCount) {
@@ -3285,29 +3285,6 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo * pFbi, const SSou · 7 unmodified lines
32853285 -- iNumThreadsRunning;
32863286 }
32873287 }
3288−#else
3289− // TODO for pthread platforms
3290− // alternate implementation using blocking due non-blocking with timeout mode not support at wels thread lib, tune back if available
3291− WelsMultipleEventsWaitAllBlocking (iNumThreadsRunning, &pCtx->pSliceThreading->pSliceCodedEvent[0]);
3292− WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
3293− if (iIndexOfSliceToBeCoded < iSliceCount) {
3294− int32_t iThreadIdx = 0;
3295− // pick up succeeding slices for threading if left
3296− while (iThreadIdx < iNumThreadsScheduled) {
3297− if (iIndexOfSliceToBeCoded >= iSliceCount)
3298− break;
3299− pCtx->pSliceThreading->pThreadPEncCtx[iThreadIdx].iSliceIndex = iIndexOfSliceToBeCoded;
3300− WelsEventSignal (&pCtx->pSliceThreading->pReadySliceCodingEvent[iThreadIdx]);
3301−
3302− ++ iIndexOfSliceToBeCoded;
3303− ++ iThreadIdx;
3304− }
3305− // update iNumThreadsRunning
3306− iNumThreadsRunning = iThreadIdx;
3307− } else {
3308− iNumThreadsRunning = 0;
3309− }
3310−#endif//_WIN32
33113288 }//while(1)
33123289
33133290 // all slices are finished coding here
@@ -3329,7 +3306,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo * pFbi, const SSou · 15 unmodified lines
33293306 return ENC_RETURN_UNEXPECTED;
33303307 }
33313308
3332− WelsMultipleEventsWaitAllBlocking (kiPartitionCnt, &pCtx->pSliceThreading->pSliceCodedEvent[0]);
3309+ WelsMultipleEventsWaitAllBlocking (kiPartitionCnt, &pCtx->pSliceThreading->pSliceCodedEvent[0], &pCtx->pSliceThreading->pSliceCodedMasterEvent);
33333310 WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
33343311
33353312 iLayerSize = AppendSliceToFrameBs (pCtx, pLayerBsInfo, kiPartitionCnt);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t