新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 C/C++编程思想 』 → Intel提供的获取某台机器CPU数量的源代码 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 2887 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: Intel提供的获取某台机器CPU数量的源代码 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 Intel提供的获取某台机器CPU数量的源代码

    //-------------------------------------------------------------------------------------------------
    //
    // Copyright ?2001, Intel Corporation . Other brands and names may be claimed as the property of others.
    //
    //
    // CPU Counting Utility
    // Date   : 10/30/2001
    // Version: 1.4
    //
    //
    //
    // File Name: CPUCount.cpp
    //
    // Note: 1) LogicalNum = Number of logical processors per PHYSICAL PROCESSOR.  If you want to count
    //       the total number of logical processors, multiply this number with the total number of
    //       physical processors (PhysicalNum)
    //
    //       2) To detect whether hyper-threading is enabled or not is to see how many logical ID exist
    //       per single physical ID in APIC
    //
    //       3) For systems that don't support hyper-threading like AMD or PIII and below. the variable
    //       LogicalNum will be set to 1 (which means number of logical processors equals to number of
    //       physical processors.)
    //    
    //       4) Hyper-threading cannot be detected when application cannot access all processors in
    //       the system. The number of physical processors will be set to 255.  Make sure to enable ALL
    //       physical processors at startup of windows, and applications calling this function, CPUCount,
    //       are NOT restricted to run on any particular logical or physical processors(can run on ALL
    //       processors.)
    //
    //       5) Windows currently can handle up to 32 processors.
    //
    //
    //-------------------------------------------------------------------------------------------------


    #define HT_BIT             0x10000000     // EDX[28]  Bit 28 is set if HT is supported
    #define FAMILY_ID          0x0F00         // EAX[11:8] Bit 8-11 contains family processor ID.
    #define PENTIUM4_ID        0x0F00         
    #define EXT_FAMILY_ID      0x0F00000      // EAX[23:20] Bit 20-23 contains extended family processor ID
    #define NUM_LOGICAL_BITS   0x00FF0000     // EBX[23:16] Bit 16-23 in ebx contains the number of logical
                                              // processors per physical processor when execute cpuid with
                                              // eax set to 1

    #define INITIAL_APIC_ID_BITS  0xFF000000  // EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique
                                              // initial APIC ID for the processor this code is running on.
                                              // Default value = 0xff if HT is not supported


    // Status Flag
    #define HT_NOT_CAPABLE           0
    #define HT_ENABLED               1
    #define HT_DISABLED              2
    #define HT_SUPPORTED_NOT_ENABLED 3
    #define HT_CANNOT_DETECT         4

    unsigned int  HTSupported(void);
    unsigned char LogicalProcPerPhysicalProc(void);
    unsigned char GetAPIC_ID(void);
    unsigned char CPUCount(unsigned char *,
            unsigned char *);


    #include <windows.h>
    #include <stdio.h>


    void main(void)
    {

       unsigned char LogicalNum   = 0,  // Number of logical CPU per ONE PHYSICAL CPU
                     PhysicalNum  = 0,  // Total number of physical processor

         HTStatusFlag = 0;  


       printf("CPU Counting Utility\n");
       printf("Version 1.4\n");
       printf("Copyright (C) 2001 Intel Corporation.  All Rights Reserved\n\n");

       HTStatusFlag = CPUCount(&LogicalNum, &PhysicalNum);

       switch(HTStatusFlag)
       {
       case HT_NOT_CAPABLE:
        printf("Hyper-threading technology not capable\n");
        break;

       case HT_DISABLED:
        printf("Hyper-threading technology disabled\n");
        break;

       case HT_ENABLED:
        printf("Hyper-threading technology enabled\n");
        break;

       case HT_SUPPORTED_NOT_ENABLED:
        printf("Hyper-threading technology capable but not enabled\n");
        break;

       case HT_CANNOT_DETECT:
        printf("Hyper-threading technology cannot be detected\n");
        break;


       }

       printf("Number of logical processors per physical processor: %d\n", LogicalNum);
       
       if (PhysicalNum != (unsigned char)-1)
          printf("Number of physical processors: %d\n", PhysicalNum);
       else
       {
       printf("Can't determine number of physical processors\n");
          printf("Make sure to enable ALL processors\n");
       }

       printf("\n\nPress Enter To Continue\n");
       getchar();
    }

    unsigned int HTSupported(void)
    {
       

    unsigned int Regedx      = 0,
               Regeax      = 0,
               VendorId[3] = {0, 0, 0};

    __try    // Verify cpuid instruction is supported
    {
      __asm
      {
       xor eax, eax          // call cpuid with eax = 0
             cpuid                 // Get vendor id string
       mov VendorId, ebx
       mov VendorId + 4, edx
       mov VendorId + 8, ecx
        
       mov eax, 1            // call cpuid with eax = 1
       cpuid
       mov Regeax, eax      // eax contains family processor type
       mov Regedx, edx      // edx has info about the availability of hyper-Threading
      
      }
    }

    __except (EXCEPTION_EXECUTE_HANDLER)
    {
      return(0);                   // cpuid is unavailable
    }

        if (((Regeax & FAMILY_ID) ==  PENTIUM4_ID) ||
      (Regeax & EXT_FAMILY_ID))
       if (VendorId[0] == 'uneG')
      if (VendorId[1] == 'Ieni')
       if (VendorId[2] == 'letn')
        return(Regedx & HT_BIT);    // Genuine Intel with hyper-Threading technology

    return 0;    // Not genuine Intel processor
      
    }


    unsigned char LogicalProcPerPhysicalProc(void)
    {

    unsigned int Regebx = 0;
    if (!HTSupported()) return (unsigned char) 1;  // HT not supported
                                                    // Logical processor = 1
    __asm
    {
      mov eax, 1
      cpuid
      mov Regebx, ebx
    }

    return (unsigned char) ((Regebx & NUM_LOGICAL_BITS) >> 16);

    }


    unsigned char GetAPIC_ID(void)
    {

    unsigned int Regebx = 0;
    if (!HTSupported()) return (unsigned char) -1;  // HT not supported
                                                     // Logical processor = 1
    __asm
    {
      mov eax, 1
      cpuid
      mov Regebx, ebx
    }

    return (unsigned char) ((Regebx & INITIAL_APIC_ID_BITS) >> 24);

    }


    unsigned char CPUCount(unsigned char *LogicalNum,
            unsigned char *PhysicalNum)
    {
    unsigned char StatusFlag  = 0;
        SYSTEM_INFO info;


        *PhysicalNum = 0;
    *LogicalNum  = 0;
        info.dwNumberOfProcessors = 0;
        GetSystemInfo (&info);

    // Number of physical processors in a non-Intel system
    // or in a 32-bit Intel system with Hyper-Threading technology disabled
        *PhysicalNum = (unsigned char) info.dwNumberOfProcessors;  

        if (HTSupported())
    {
      unsigned char HT_Enabled = 0;

            *LogicalNum= LogicalProcPerPhysicalProc();

      if (*LogicalNum >= 1)    // >1 Doesn't mean HT is enabled in the BIOS
                            //
      {
                HANDLE hCurrentProcessHandle;
       DWORD  dwProcessAffinity;
       DWORD  dwSystemAffinity;
       DWORD  dwAffinityMask;

       // Calculate the appropriate  shifts and mask based on the
       // number of logical processors.

       unsigned char i = 1,
                  PHY_ID_MASK  = 0xFF,
                     PHY_ID_SHIFT = 0;

       while (i < *LogicalNum)
       {
        i *= 2;
                  PHY_ID_MASK  <<= 1;
                 PHY_ID_SHIFT++;

       }
        
       hCurrentProcessHandle = GetCurrentProcess();
       GetProcessAffinityMask(hCurrentProcessHandle, &dwProcessAffinity,
                                                  &dwSystemAffinity);

       // Check if available process affinity mask is equal to the
       // available system affinity mask
                if (dwProcessAffinity != dwSystemAffinity)
       {
                    StatusFlag = HT_CANNOT_DETECT;
        *PhysicalNum = (unsigned char)-1;
        return StatusFlag;
       }
          dwAffinityMask = 1;
          while (dwAffinityMask != 0 && dwAffinityMask <= dwProcessAffinity)
          {
            // Check if this CPU is available
          if (dwAffinityMask & dwProcessAffinity)
          {
                         if (SetProcessAffinityMask(hCurrentProcessHandle,
                                  dwAffinityMask))
          {
           unsigned char APIC_ID,
                      LOG_ID,
                PHY_ID;

           Sleep(0); // Give OS time to switch CPU

                             APIC_ID = GetAPIC_ID();
           LOG_ID  = APIC_ID & ~PHY_ID_MASK;
           PHY_ID  = APIC_ID >> PHY_ID_SHIFT;
      
               if (LOG_ID != 0)  HT_Enabled = 1;

          }

          }

          dwAffinityMask = dwAffinityMask << 1;

          }
                 
       // Reset the processor affinity
        SetProcessAffinityMask(hCurrentProcessHandle, dwProcessAffinity);

                
       if (*LogicalNum == 1)  // Normal P4 : HT is disabled in hardware
           StatusFlag = HT_DISABLED;

       else
        if (HT_Enabled)
        {
                         // Total physical processors in a Hyper-Threading enabled system.
                   *PhysicalNum /= (*LogicalNum);
                StatusFlag = HT_ENABLED;
        }
        else StatusFlag = HT_SUPPORTED_NOT_ENABLED;

      }

    }
    else
    {
      // Processors do not have Hyper-Threading technology
      StatusFlag = HT_NOT_CAPABLE;
            *LogicalNum = 1;
            
    }
    return StatusFlag;
    }


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/4/15 16:05:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/18 15:56:26

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    3,968.750ms