<strike id="kiyse"></strike>
  • <tr id="kiyse"></tr>
  • <strike id="kiyse"></strike><samp id="kiyse"><tbody id="kiyse"></tbody></samp>
    <strike id="kiyse"><s id="kiyse"></s></strike>
    <tr id="kiyse"></tr>
    <noframes id="kiyse"><code id="kiyse"></code></noframes>
    <th id="kiyse"></th>
    <samp id="kiyse"></samp>
  • <th id="kiyse"><s id="kiyse"></s></th>
  • 基于WEC7的多核系統編程方法

     2017-3-21     作者:劉乾坤         
    文章標簽:C/C++

      Windows Embedded Compact 7(WEC7)一個最重要的特性就是對多核處理器的支持(Symmetric Multi-Processing(SMP)),ESM6802是英創公司推出的基于Freescale  i.MX6DL雙核處理器的高性能工控主板,預裝正版WEC7嵌入式操作系統,并且內核啟用了對SMP的支持。在多個程序同時執行的情況下,支持SMP的多核系統具有比單處理器更好的性能,因為不同的程序可以在不同的處理器上同時運行,支持SMP還可以實現在一個核心上執行硬實時應用程序,而用戶界面(UI)或其它應用程序可在另一個核心上運行,以提高系統的效率。


      WEC7提供了一組處理多核系統上線程和處理器調度的SMP API接口函數:

      https://msdn.microsoft.com/en-us/library/gg154433(v=winembedded.70).aspx


      其中應用程序常用的SMP API如下所示:


     GetCurrentProcessorNumber 獲取在調用此函數期間當前線程正在運行的處理器
     CeGetIdleTimeEx 獲取指定處理器的空閑時間
     CeGetProcessAffinity 獲取指定進程的進程關聯
     CeGetThreadAffinity 獲取指定線程的線程關聯
     CeGetTotalProcessors 獲取系統中的處理器核心總數
     CeSetProcessAffinity 為指定的進程設置處理器關聯
     CeSetThreadAffinity 為指定的線程設置處理器關聯


      默認情況下,WEC7系統會自動的將系統負載分配到CPU的所有核心上運行,應用程序不需要做任何設置。但根據不同的應用場景,應用程序也可以利用SMP API手動的設置每個進程、每個線程在指定的CPU核心上運行,這里以計算ESM6802 i.MX6DL CPU每個核心的負載為例,介紹WEC7 SMP API的使用方法。


      應用程序首先通過CeGetTotalProcessors函數獲取當前系統總的處理器(核心)個數,然后根據CPU核心個數創建相同數量的CPUIdleMonitorThread應用線程用于計算CPU負載,在創建線程后通過CeSetThreadAffinity函數將所創建的線程固定在指定的CPU核心上運行。CPUIdleMonitorThread線程函數在執行時先調用GetCurrentProcessorNumber函數取得執行當前線程的CPU核,而后再利用CeGetIdleTimeEx函數最終計算出每個CPU核心的負載率。完整的例子代碼如下:


      #include "stdafx.h"

      // time in seconds to run the monitor thread

      #define IDLE_MONITOR_TIME   100

     

      HANDLE g_hMonitorThreads[4];

     

      UINT32 CPUIdleMonitorThread(PVOID pContext)

      {

          UINT32 nCPUId = ((UINT32*)pContext)[0];

          UINT32 nRunTime = ((UINT32*)pContext)[1];

          UINT32 nIdleBefore, nIdleAfter, nIdleDiff, nIdlePercent;

          UINT32 nReturn = ERROR_SUCCESS;

     

          LARGE_INTEGER pcBefore = { 0, 0 };

          LARGE_INTEGER pcAfter = { 0, 0 };

          LARGE_INTEGER diff;

          LARGE_INTEGER freq;

     

          RETAILMSG(1, (L"[CPU%d] Run monitor thread for %d seconds\r\n", nCPUId, nRunTime));

     

          // The processor number is a 1-based index.

          QueryPerformanceFrequency(&freq);

     

          while (nRunTime > 0)

          {

              nCPUId = GetCurrentProcessorNumber();

              CeGetIdleTimeEx(nCPUId, (LPDWORD)&nIdleBefore);

     

              QueryPerformanceCounter(&pcBefore);

              Sleep(2000);

              QueryPerformanceCounter(&pcAfter);

     

              CeGetIdleTimeEx(nCPUId, (LPDWORD)&nIdleAfter);

     

              diff.QuadPart = (pcAfter.QuadPart - pcBefore.QuadPart) * 1000 / freq.QuadPart;

              nIdleDiff = nIdleAfter - nIdleBefore;

              nIdlePercent = nIdleDiff / 20;

     

              RETAILMSG(1, (L"[CPU%d] Sleep: 2000 ms (actual:%d ms)  Idle: %03d ms (CPU%d = %d%%)\r\n",

                   nCPUId, diff.LowPart, nIdleDiff, nCPUId, 100 - nIdlePercent));

              nRunTime--;

          }

     

          SetEvent(g_hMonitorThreads[nCPUId - 1]);

          return nReturn;

      }

     

      int WINAPI WinMain(HINSTANCE hInstance,

                         HINSTANCE hPrevInstance,

                         LPTSTR     lpCmdLine,

                         int       nCmdShow)

      {

          UINT32 nCPUCount;

          UINT32 nTemp = 0;

          UINT32 i;

          UINT32 nParam[8] = { 1, IDLE_MONITOR_TIME, 2, IDLE_MONITOR_TIME, 3, IDLE_MONITOR_TIME, 4, IDLE_MONITOR_TIME };

     

          nCPUCount = CeGetTotalProcessors();

     

          for(i = 0; i < nCPUCount; i++)

              g_hMonitorThreads[i] = CreateEvent(NULL, TRUE, FALSE, NULL);

       

          nTemp = 1;

     

          CeSetThreadAffinity(GetCurrentThread(), 1);

     

          for (i = 1; i < nCPUCount; i++)

          {

              HANDLE hThread = CreateThread(

                  NULL,

                  0,

                  (LPTHREAD_START_ROUTINE)CPUIdleMonitorThread,

                  &nParam[i * 2],

                  CREATE_SUSPENDED,

                  NULL);

     

              if (NULL != hThread)

              {

                  CeSetThreadAffinity(hThread, i + 1);

                  ResumeThread(hThread);

                  Sleep(0);

                  CloseHandle(hThread);

                  nTemp++;

              }

              else

              {

                  SetEvent(g_hMonitorThreads[i]);

              }

          }

     

          CPUIdleMonitorThread(&nParam[0]);

     

          Sleep(2000);

          for(i = 0; i < nCPUCount; i++)

              WaitForSingleObject(g_hMonitorThreads[i], (IDLE_MONITOR_TIME + 5) * 1000);

     

          RETAILMSG(1, (L"[CPULOAD] Number of CPUs monitored: %d\r\n", nTemp));

     

          return 0;

      }

    文章標簽:C/C++
    国产综合精品女在线观看| 精品久久久久中文字幕日本| 精品剧情v国产在线麻豆| 日本aⅴ精品中文字幕| 亚洲国产精品自在拍在线播放| 国产精品久久久久久福利漫画| 国产精品后入内射日本在线观看| 国产精品jlzz视频| 久久99这里只有精品国产| 久久国产精品免费视频| 国产亚洲美女精品久久久| 国产精品黄页在线播放免费| 亚洲中文久久精品无码1| 国产精品三级在线观看无码| 国产精品自产拍在线18禁| 在线观看免费精品国产| 亚洲а∨天堂久久精品9966| 99re6热视频精品免费观看| 国内精品免费在线观看 | 国产精品自拍亚洲| 日本精品www色| 久久精品人人做人人爽97| 国产精品久久久久国产A级| 国产在线精品一区免费香蕉| 精品人妻人人做人人爽夜夜爽 | 精品福利一区3d动漫| 成人h动漫精品一区二区无码| 99热婷婷国产精品综合| 精品国产爽爽AV| 国产精品伊人久久伊人电影| 夜夜精品无码一区二区三区| 国产精品亚洲片在线va| 久クク成人精品中文字幕| 亚洲高清日韩精品第一区| 亚洲精品美女久久777777| 人与狗精品AA毛片| 日韩精品亚洲aⅴ在线影院| 国产在线精品一区二区三区不卡 | 91精品国产91久久久久久青草| 久久精品一本到99热免费| 亚洲国产精品成人综合久久久|