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/slice_multi_threading.cpp (1 of 3 files). Show all

Unified · Split

codec/encoder/core/src/slice_multi_threading.cpp+13−3
@@ -351,10 +351,11 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara · 350 unmodified lines
351 351
352 MT_TRACE_LOG ((*ppCtx), WELS_LOG_INFO, "encpEncCtx= 0x%p\n", (void*) (*ppCtx));352 MT_TRACE_LOG ((*ppCtx), WELS_LOG_INFO, "encpEncCtx= 0x%p\n", (void*) (*ppCtx));
353 353
354 char name[SEM_NAME_MAX] = {0};
355 WELS_THREAD_ERROR_CODE err = 0;
356
354 iIdx = 0;357 iIdx = 0;
355 while (iIdx < iThreadNum) {358 while (iIdx < iThreadNum) {
356 char name[SEM_NAME_MAX] = {0};
357 WELS_THREAD_ERROR_CODE err = 0;
358 pSmt->pThreadPEncCtx[iIdx].pWelsPEncCtx = (void*) (*ppCtx);359 pSmt->pThreadPEncCtx[iIdx].pWelsPEncCtx = (void*) (*ppCtx);
359 pSmt->pThreadPEncCtx[iIdx].iSliceIndex = iIdx;360 pSmt->pThreadPEncCtx[iIdx].iSliceIndex = iIdx;
360 pSmt->pThreadPEncCtx[iIdx].iThreadIndex = iIdx;361 pSmt->pThreadPEncCtx[iIdx].iThreadIndex = iIdx;
@@ -386,6 +387,10 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara · 25 unmodified lines
386 ++ iIdx;387 ++ iIdx;
387 }388 }
388 389
390 WelsSnprintf (name, SEM_NAME_MAX, "scm%s", pSmt->eventNamespace);
391 err = WelsEventOpen (&pSmt->pSliceCodedMasterEvent, name);
392 MT_TRACE_LOG ((*ppCtx), WELS_LOG_INFO, "[MT] Open pSliceCodedMasterEvent named(%s) ret%d err%d\n", name, err, errno);
393
389 (*ppCtx)->pSliceBs = (SWelsSliceBs*)pMa->WelsMalloc (sizeof (SWelsSliceBs) * iMaxSliceNum, "pSliceBs");394 (*ppCtx)->pSliceBs = (SWelsSliceBs*)pMa->WelsMalloc (sizeof (SWelsSliceBs) * iMaxSliceNum, "pSliceBs");
390 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSliceBs), FreeMemorySvc (ppCtx))395 WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSliceBs), FreeMemorySvc (ppCtx))
391 396
@@ -444,8 +449,8 @@ void ReleaseMtResource (sWelsEncCtx** ppCtx) { · 52 unmodified lines
444 if (NULL == pSmt)449 if (NULL == pSmt)
445 return;450 return;
446 451
452 char ename[SEM_NAME_MAX] = {0};
447 while (iIdx < iThreadNum) {453 while (iIdx < iThreadNum) {
448 char ename[SEM_NAME_MAX] = {0};
449 // length of semaphore name should be system constrained at least on mac 10.7454 // length of semaphore name should be system constrained at least on mac 10.7
450#ifdef _WIN32455#ifdef _WIN32
451 if (pSmt->pThreadHandles != NULL && pSmt->pThreadHandles[iIdx] != NULL)456 if (pSmt->pThreadHandles != NULL && pSmt->pThreadHandles[iIdx] != NULL)
@@ -467,6 +472,8 @@ void ReleaseMtResource (sWelsEncCtx** ppCtx) { · 15 unmodified lines
467 472
468 ++ iIdx;473 ++ iIdx;
469 }474 }
475 WelsSnprintf (ename, SEM_NAME_MAX, "scm%s", pSmt->eventNamespace);
476 WelsEventClose (&pSmt->pSliceCodedMasterEvent, ename);
470 477
471 WelsMutexDestroy (&pSmt->mutexSliceNumUpdate);478 WelsMutexDestroy (&pSmt->mutexSliceNumUpdate);
472 WelsMutexDestroy (&((*ppCtx)->mutexEncoderError));479 WelsMutexDestroy (&((*ppCtx)->mutexEncoderError));
@@ -864,6 +871,8 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { · 391 unmodified lines
864 871
865 WelsEventSignal (872 WelsEventSignal (
866 &pEncPEncCtx->pSliceThreading->pSliceCodedEvent[iEventIdx]); // mean finished coding current pSlice873 &pEncPEncCtx->pSliceThreading->pSliceCodedEvent[iEventIdx]); // mean finished coding current pSlice
874 WelsEventSignal (
875 &pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent);
867 } else { // for SM_DYN_SLICE parallelization876 } else { // for SM_DYN_SLICE parallelization
868 SSliceCtx* pSliceCtx = pCurDq->pSliceEncCtx;877 SSliceCtx* pSliceCtx = pCurDq->pSliceEncCtx;
869 const int32_t kiPartitionId = iThreadIdx;878 const int32_t kiPartitionId = iThreadIdx;
@@ -967,6 +976,7 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { · 97 unmodified lines
967 break;976 break;
968 977
969 WelsEventSignal (&pEncPEncCtx->pSliceThreading->pSliceCodedEvent[iEventIdx]); // mean finished coding current pSlice978 WelsEventSignal (&pEncPEncCtx->pSliceThreading->pSliceCodedEvent[iEventIdx]); // mean finished coding current pSlice
979 WelsEventSignal (&pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent);
970 }980 }
971 }981 }
972#ifdef _WIN32982#ifdef _WIN32

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