#include <mil.h>
#define IMAGE_FILE M_IMAGE_PATH MIL_TEXT("LargeWafer.mim")
#define ROTATE_ANGLE -15
#define MINIMUM_BENCHMARK_TIME 2.0
#define ESTIMATION_NB_LOOP 10
#define DEFAULT_NB_LOOP 100
typedef struct
{
MIL_ID MilSourceImage;
MIL_ID MilDestinationImage;
} PROC_PARAM;
void Benchmark(PROC_PARAM& ProcParamPtr, MIL_DOUBLE& Time, MIL_DOUBLE& FramesPerSecond);
void ProcessingInit(MIL_ID MilSystem, PROC_PARAM& ProcParamPtr);
void ProcessingExecute(PROC_PARAM& ProcParamPtr);
void ProcessingFree(PROC_PARAM& ProcParamPtr);
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem,
MilDisplay,
MilDisplayImage,
MilSystemOwnerApplication,
MilSystemCurrentThreadId;
PROC_PARAM ProcessingParam;
MIL_DOUBLE TimeAllCores, TimeAllCoresNoCS, TimeOneCore;
MIL_DOUBLE FPSAllCores, FPSAllCoresNoCS, FPSOneCore;
MIL_INT NbCoresUsed, NbCoresUsedNoCS;
bool UseGPUSystem;
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem,
&MilDisplay, M_NULL, M_NULL);
MsysInquire(MilSystem, M_OWNER_APPLICATION, &MilSystemOwnerApplication);
MsysInquire(MilSystem, M_CURRENT_THREAD_ID, &MilSystemCurrentThreadId);
UseGPUSystem = MsysInquire(MilSystem, M_SYSTEM_TYPE, M_NULL) == M_SYSTEM_GPU_TYPE;
MbufRestore(IMAGE_FILE, MilSystem, &MilDisplayImage);
MdispSelect(MilDisplay, MilDisplayImage);
ProcessingInit(MilSystem, ProcessingParam);
MosPrintf(MIL_TEXT("\nPROCESSING FUNCTION BENCHMARKING:\n"));
MosPrintf(MIL_TEXT("---------------------------------\n\n"));
MosPrintf(MIL_TEXT("This program times a processing function under "));
MosPrintf(MIL_TEXT("different conditions.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to start.\n\n"));
MosGetch();
MosPrintf(MIL_TEXT("PROCESSING TIME FOR %ldx%ld:\n" ),
MbufInquire(ProcessingParam.MilDestinationImage, M_SIZE_X, NULL),
MbufInquire(ProcessingParam.MilDestinationImage, M_SIZE_Y, NULL));
MosPrintf(MIL_TEXT("------------------------------\n\n"));
if (!UseGPUSystem)
{
MappControlMp(MilSystemOwnerApplication, M_MP_USE, M_DEFAULT, M_ENABLE, M_NULL);
MappControlMp(MilSystemOwnerApplication, M_CORE_SHARING, M_DEFAULT, M_ENABLE, M_NULL);
MthrInquireMp(MilSystemCurrentThreadId, M_CORE_NUM_EFFECTIVE, M_DEFAULT, M_DEFAULT, &NbCoresUsed);
if (NbCoresUsed > 1)
{
Benchmark(ProcessingParam, TimeAllCores, FPSAllCores);
MbufCopy(ProcessingParam.MilDestinationImage, MilDisplayImage);
MosPrintf(MIL_TEXT("Using multi-processing (%3ld CPU cores): %5.3f ms (%6.1f fps)\n"),
NbCoresUsed, TimeAllCores, FPSAllCores);
}
MappControlMp(MilSystemOwnerApplication, M_MP_USE, M_DEFAULT, M_DEFAULT, M_NULL);
MappControlMp(MilSystemOwnerApplication, M_CORE_SHARING, M_DEFAULT, M_DEFAULT, M_NULL);
MappControlMp(MilSystemOwnerApplication, M_MP_USE, M_DEFAULT, M_ENABLE, M_NULL);
MappControlMp(MilSystemOwnerApplication, M_CORE_SHARING, M_DEFAULT, M_DISABLE, M_NULL);
MthrInquireMp(MilSystemCurrentThreadId, M_CORE_NUM_EFFECTIVE, M_DEFAULT, M_DEFAULT, &NbCoresUsedNoCS);
if (NbCoresUsedNoCS != NbCoresUsed)
{
Benchmark(ProcessingParam, TimeAllCoresNoCS, FPSAllCoresNoCS);
MbufCopy(ProcessingParam.MilDestinationImage, MilDisplayImage);
MosPrintf(MIL_TEXT("Using multi-processing (%3ld CPU cores): %5.3f ms (%6.1f fps), no Hyper-Thread.\n"),
NbCoresUsedNoCS, TimeAllCoresNoCS, FPSAllCoresNoCS);
}
MappControlMp(MilSystemOwnerApplication, M_MP_USE, M_DEFAULT, M_DEFAULT, M_NULL);
MappControlMp(MilSystemOwnerApplication, M_CORE_SHARING, M_DEFAULT, M_DEFAULT, M_NULL);
MappControlMp(MilSystemOwnerApplication, M_MP_USE, M_DEFAULT, M_DISABLE, M_NULL);
Benchmark(ProcessingParam, TimeOneCore, FPSOneCore);
MbufCopy(ProcessingParam.MilDestinationImage, MilDisplayImage);
MosPrintf(MIL_TEXT("Without multi-processing ( 1 CPU core ): %5.3f ms (%6.1f fps)\n\n"),
TimeOneCore, FPSOneCore);
MappControlMp(MilSystemOwnerApplication, M_MP_USE, M_DEFAULT, M_DEFAULT, M_NULL);
if (NbCoresUsed > 1)
{
MosPrintf(MIL_TEXT("Benchmark is %.1f times faster with multi-processing.\n"),
TimeOneCore/TimeAllCores);
}
if (NbCoresUsedNoCS != NbCoresUsed)
{
MosPrintf(MIL_TEXT("Benchmark is %.1f times faster with multi-processing and no Hyper-Thread.\n\n"),
TimeOneCore/TimeAllCoresNoCS);
}
}
else
{
Benchmark(ProcessingParam, TimeAllCores, FPSAllCores);
MbufCopy(ProcessingParam.MilDestinationImage, MilDisplayImage);
MosPrintf(MIL_TEXT("Using GPU: %5.3f ms (%6.1f fps)\n"), TimeAllCores, FPSAllCores);
}
MosPrintf(MIL_TEXT("Press <Enter> to end.\n"));
MosGetch();
ProcessingFree(ProcessingParam);
MdispSelect(MilDisplay, M_NULL);
MbufFree(MilDisplayImage);
MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL);
return 0;
}
void Benchmark(PROC_PARAM& ProcParamPtr, MIL_DOUBLE& Time, MIL_DOUBLE& FramesPerSecond)
{
MIL_INT EstimatedNbLoop = DEFAULT_NB_LOOP;
MIL_DOUBLE StartTime, EndTime;
MIL_DOUBLE MinTime = 0;
MIL_INT n;
MthrWait(M_DEFAULT, M_THREAD_WAIT, M_NULL);
MappTimer(M_DEFAULT, M_TIMER_READ, &StartTime);
ProcessingExecute(ProcParamPtr);
MthrWait(M_DEFAULT, M_THREAD_WAIT, M_NULL);
MappTimer(M_DEFAULT, M_TIMER_READ, &EndTime);
MinTime = EndTime-StartTime;
for (n = 0; n < ESTIMATION_NB_LOOP; n++)
{
MappTimer(M_DEFAULT, M_TIMER_READ, &StartTime);
ProcessingExecute(ProcParamPtr);
MthrWait(M_DEFAULT, M_THREAD_WAIT, M_NULL);
MappTimer(M_DEFAULT, M_TIMER_READ, &EndTime);
Time = EndTime-StartTime;
MinTime = (Time<MinTime)?Time:MinTime;
}
if (MinTime > 0)
EstimatedNbLoop = (MIL_INT)(MINIMUM_BENCHMARK_TIME/MinTime)+1;
MappTimer(M_DEFAULT, M_TIMER_READ, &StartTime);
for (n = 0; n < EstimatedNbLoop; n++)
ProcessingExecute(ProcParamPtr);
MthrWait(M_DEFAULT, M_THREAD_WAIT, M_NULL);
MappTimer(M_DEFAULT, M_TIMER_READ, &EndTime);
Time = EndTime-StartTime;
FramesPerSecond = EstimatedNbLoop/Time;
Time = Time*1000/EstimatedNbLoop;
}
void ProcessingInit(MIL_ID MilSystem, PROC_PARAM& ProcParamPtr)
{
MbufAllocColor(MilSystem,
MbufDiskInquire(IMAGE_FILE, M_SIZE_BAND, M_NULL),
MbufDiskInquire(IMAGE_FILE, M_SIZE_X, M_NULL),
MbufDiskInquire(IMAGE_FILE, M_SIZE_Y, M_NULL),
MbufDiskInquire(IMAGE_FILE, M_SIZE_BIT, M_NULL)+M_UNSIGNED,
M_IMAGE+M_PROC, &ProcParamPtr.MilSourceImage);
MbufLoad(IMAGE_FILE, ProcParamPtr.MilSourceImage);
MbufAllocColor(MilSystem,
MbufDiskInquire(IMAGE_FILE, M_SIZE_BAND, M_NULL),
MbufDiskInquire(IMAGE_FILE, M_SIZE_X, M_NULL),
MbufDiskInquire(IMAGE_FILE, M_SIZE_Y, M_NULL),
MbufDiskInquire(IMAGE_FILE, M_SIZE_BIT, M_NULL)+M_UNSIGNED,
M_IMAGE+M_PROC, &ProcParamPtr.MilDestinationImage);
}
void ProcessingExecute(PROC_PARAM& ProcParamPtr)
{
MimRotate(ProcParamPtr.MilSourceImage, ProcParamPtr.MilDestinationImage, ROTATE_ANGLE,
M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_BILINEAR+M_OVERSCAN_CLEAR);
}
void ProcessingFree(PROC_PARAM& ProcParamPtr)
{
MbufFree(ProcParamPtr.MilSourceImage);
MbufFree(ProcParamPtr.MilDestinationImage);
}