山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他CPUの物理CPU数・ソケット数等を取得(32/64bit)・他のプログラムで他のCPUをエミュレーションする方法
他のプログラムで他のCPUをエミュレーションする方法
例えば、CPUがサポートしているSIMD(MMX,SSE,SSE2,SSE3,SSE3,AVX,AVX2)とWindowsのサポート状況を表示(32/64bit) は起動したシステムのCPUIDに基づき動作しているが、他のCPUに置き換える場合は、元のソースコードに赤字の行を追加する。
コンパイル時には、エミュレーション用のヘッダーファイルAtom_D2701_2130MHz_emu.hとcpu.h cpu.cppをプロジェクトに加える必要がある。
コンパイル時には、エミュレーション用のヘッダーファイルAtom_D2701_2130MHz_emu.hとcpu.h cpu.cppをプロジェクトに加える必要がある。
// SIMD拡張命令のサポート状況を表示
// Visual C++ 2008,2013
#include <windows.h>
#include <tchar.h>
#include <intrin.h>
#if 1800 <= _MSC_VER // Visual C++ 2013以上
#include <VersionHelpers.h>
#else
#ifndef _WIN32_WINNT_WIN7
#define _WIN32_WINNT_WIN7 0x0601
#endif
inline bool IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor){
OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, { 0 }, 0, 0 };
DWORDLONG const dwlConditionMask = VerSetConditionMask(
VerSetConditionMask(
VerSetConditionMask(
0, VER_MAJORVERSION, VER_GREATER_EQUAL),
VER_MINORVERSION, VER_GREATER_EQUAL),
VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
osvi.dwMajorVersion = wMajorVersion;
osvi.dwMinorVersion = wMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE;
}
inline bool IsWindows7SP1OrGreater(void){
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 1);
}
#endif
#include "cpu.h"
#include "Atom_D2701_2130MHz_emu.h"
CPU_EMU_CLASS cpu_emu;
#define __cpuid(info,eax) cpu.cpuid( (info), (eax) )
#define __cpuidex(info,eax,ecx) cpu.cpuid( (info), (eax),(ecx) )
#define SetThreadAffinityMask(h,m) cpu.emuSetThreadAffinityMask((h),(m))
#define GetSystemInfo(s) cpu.emuGetSystemInfo((s))
// CPUID 1 ECX
#define AVX_READY (1<<28)
#define SSE42_READY (1<<20)
#define SSE41_READY (1<<19)
#define SSSE3_READY (1<<9)
#define SSE3_READY (1)
// CPUID 1 EDX
#define IA64_READY (1<<30)
#define HTT_READY (1<<8)
#define SSE2_READY (1<<26)
#define SSE_READY (1<<25)
#define MMX_READY (1<<23)
#define FPU_READY (1)
// CPUID 1 EBX
#define AVX2_READY (1<<5)
inline int _MSC_CVER(void) {
int cver = 0;
#if _MSC_VER==1400
cver = 2005;
#endif
#if _MSC_VER==1500
cver = 2008;
#endif
#if _MSC_VER==1600
cver = 2010;
#endif
#if _MSC_VER==1700
cver = 2012;
#endif
#if _MSC_VER==1800
cver = 2013;
#endif
return cver;
}
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow){
CPU cpu(1);
cpu.add(0,&cpu_emu);
cpu.init();
cpu.parse();
TCHAR cpuname[4*4*4];
TCHAR inst[256];
TCHAR buf[256];
int cver = 0;
TCHAR* project;
TCHAR* win;
TCHAR* dll;
#ifdef _DEBUG
project = _TEXT("Debug");
#else
project = _TEXT("Release");
#endif
#ifdef _WIN64
win=_TEXT("x64");
#else
win = _TEXT("Win32");
#endif
#ifdef _DLL
dll = _TEXT("マルチスレッドDLL");
#else
dll = _TEXT("マルチスレッド");
#endif
cver=_MSC_CVER();
_stprintf_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("ビルド Visual C++ %i %s %s %s\r\n"), cver,project,win,dll);
inst[0] = 0;
cpuname[0] = 0;
int CPUInfo[4];
__cpuid(CPUInfo, 0x80000000);
if (0x80000002 <= CPUInfo[0]){ // プロセッサブランド文字列の取得が可能である
int CPUInfoV[3][4];
__cpuid(CPUInfoV[0], 0x80000002);
__cpuid(CPUInfoV[1], 0x80000003);
__cpuid(CPUInfoV[2], 0x80000004);
char* p = (char*)CPUInfoV;
for (int n = 0; n < 4*4*3; n++){
cpuname[n] = *p++;
}
_tcscat_s(buf, sizeof(buf) / sizeof(TCHAR), cpuname);
_tcscat_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("\r\n"));
}
__cpuid(CPUInfo, 1);
if (CPUInfo[3] & MMX_READY){
_tcscat_s(inst,sizeof(inst)/sizeof(TCHAR),_TEXT("MMX "));
}
if (CPUInfo[3] & SSE_READY){
_tcscat_s(inst, sizeof(inst) / sizeof(TCHAR), _TEXT("SSE "));
}
if (CPUInfo[3] & SSE2_READY){
_tcscat_s(inst, sizeof(inst) / sizeof(TCHAR), _TEXT("SSE2 "));
}
if (CPUInfo[2] & SSE3_READY){
_tcscat_s(inst, sizeof(inst) / sizeof(TCHAR), _TEXT("SSE3 "));
}
if (CPUInfo[2] & SSSE3_READY){
_tcscat_s(inst, sizeof(inst) / sizeof(TCHAR), _TEXT("SSSE3 "));
}
if (CPUInfo[2] & SSE41_READY){
_tcscat_s(inst, sizeof(inst) / sizeof(TCHAR), _TEXT("SSE4.1 "));
}
if (CPUInfo[2] & SSE42_READY){
_tcscat_s(inst, sizeof(inst) / sizeof(TCHAR), _TEXT("SSE4.2 "));
}
if (CPUInfo[2] & AVX_READY){
_tcscat_s(inst, sizeof(inst) / sizeof(TCHAR), _TEXT("AVX "));
}
__cpuid(CPUInfo, 1);
if (CPUInfo[1] & AVX2_READY){
_tcscat_s(inst, sizeof(inst) / sizeof(TCHAR), _TEXT("AVX2 "));
}
if (inst[0]){
_tcscat_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("CPUサポート "));
_tcscat_s(buf, sizeof(buf) / sizeof(TCHAR), inst);
_tcscat_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("\r\n"));
}
if (IsWindows7SP1OrGreater()){
_tcscat_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("OS AVX Suport"));
}
else{
_tcscat_s(buf, sizeof(buf) / sizeof(TCHAR), _TEXT("OS AVX Not Suport"));
}
MessageBox(0, buf, _TEXT("システムのSIMD命令のサポート状況"), MB_OK);
return (int)0;
}
Pentium4 上で実行しているにもかかわらずAtomに変身している。
Copyright (C) 2012 山本ワールド All Rights Reserved.