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
3225 return ENC_RETURN_UNEXPECTED;3225 return ENC_RETURN_UNEXPECTED;
3226 }3226 }
3227 3227
3228 WelsMultipleEventsWaitAllBlocking (iSliceCount, &pCtx->pSliceThreading->pSliceCodedEvent[0]);3228 WelsMultipleEventsWaitAllBlocking (iSliceCount, &pCtx->pSliceThreading->pSliceCodedEvent[0], &pCtx->pSliceThreading->pSliceCodedMasterEvent);
3229 3229
3230 3230
3231 // all slices are finished coding here3231 // all slices are finished coding here
@@ -3266,12 +3266,12 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo * pFbi, const SSou · 34 unmodified lines
3266 while (1) {3266 while (1) {
3267 if (iIndexOfSliceToBeCoded >= iSliceCount && iNumThreadsRunning <= 0)3267 if (iIndexOfSliceToBeCoded >= iSliceCount && iNumThreadsRunning <= 0)
3268 break;3268 break;
3269#ifdef _WIN32
3270 WELS_THREAD_ERROR_CODE lwait = 0;3269 WELS_THREAD_ERROR_CODE lwait = 0;
3271 int32_t iEventId = -1;3270 int32_t iEventId = -1;
3272 3271
3273 lwait = WelsMultipleEventsWaitSingleBlocking (iNumThreadsScheduled,3272 lwait = WelsMultipleEventsWaitSingleBlocking (iNumThreadsScheduled,
3274 &pCtx->pSliceThreading->pSliceCodedEvent[0]);3273 &pCtx->pSliceThreading->pSliceCodedEvent[0],
3274 &pCtx->pSliceThreading->pSliceCodedMasterEvent);
3275 iEventId = (int32_t) (lwait - WELS_THREAD_ERROR_WAIT_OBJECT_0);3275 iEventId = (int32_t) (lwait - WELS_THREAD_ERROR_WAIT_OBJECT_0);
3276 if (iEventId >= 0 && iEventId < iNumThreadsScheduled) {3276 if (iEventId >= 0 && iEventId < iNumThreadsScheduled) {
3277 if (iIndexOfSliceToBeCoded < iSliceCount) {3277 if (iIndexOfSliceToBeCoded < iSliceCount) {
@@ -3285,29 +3285,6 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo * pFbi, const SSou · 7 unmodified lines
3285 -- iNumThreadsRunning;3285 -- iNumThreadsRunning;
3286 }3286 }
3287 }3287 }
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
3311 }//while(1)3288 }//while(1)
3312 3289
3313 // all slices are finished coding here3290 // all slices are finished coding here
@@ -3329,7 +3306,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo * pFbi, const SSou · 15 unmodified lines
3329 return ENC_RETURN_UNEXPECTED;3306 return ENC_RETURN_UNEXPECTED;
3330 }3307 }
3331 3308
3332 WelsMultipleEventsWaitAllBlocking (kiPartitionCnt, &pCtx->pSliceThreading->pSliceCodedEvent[0]);3309 WelsMultipleEventsWaitAllBlocking (kiPartitionCnt, &pCtx->pSliceThreading->pSliceCodedEvent[0], &pCtx->pSliceThreading->pSliceCodedMasterEvent);
3333 WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)3310 WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
3334 3311
3335 iLayerSize = AppendSliceToFrameBs (pCtx, pLayerBsInfo, kiPartitionCnt);3312 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