2009-11-03 38 views
20

Tôi muốn biết liệu có ai đó ở đây có một số ví dụ hay về triển khai CPU C++ có thể được tham chiếu từ bất kỳ ngôn ngữ .net được quản lý nào.Triển khai CPUID trong C++

Ngoài ra, đây có phải là trường hợp không, tôi có nên biết một số khác biệt thực hiện nhất định giữa X86 và X64 không?

Tôi muốn sử dụng CPUID để nhận thông tin trên máy mà phần mềm của tôi đang chạy (crashreporting etc ...) và tôi muốn giữ mọi thứ tương thích rộng rãi nhất có thể.

lý do Primary tôi hỏi là vì tôi là một tổng Noob khi nói đến viết những gì có thể sẽ được tất cả hướng dẫn của máy mặc dù tôi có kiến ​​thức cơ bản về thanh ghi CPU và vân vân ...

Trước khi mọi người bắt đầu nói với tôi cho Google: Tôi đã tìm thấy một số ví dụ trực tuyến, nhưng thường chúng không có nghĩa là cho phép tương tác từ mã được quản lý và không có ví dụ nào nhắm đến cả X86 và X64. Hầu hết các ví dụ dường như là X86 cụ thể.

Trả lời

38

Tiếp cận thông tin CPUID liệu thực sự là rất dễ dàng, đây là một lớp C++ cho rằng trong đó hoạt động trong Windows, Linux và OSX:

#ifndef CPUID_H 
#define CPUID_H 

#ifdef _WIN32 
#include <limits.h> 
#include <intrin.h> 
typedef unsigned __int32 uint32_t; 

#else 
#include <stdint.h> 
#endif 

class CPUID { 
    uint32_t regs[4]; 

public: 
    explicit CPUID(unsigned i) { 
#ifdef _WIN32 
    __cpuid((int *)regs, (int)i); 

#else 
    asm volatile 
     ("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) 
     : "a" (i), "c" (0)); 
    // ECX is set to zero for CPUID function 4 
#endif 
    } 

    const uint32_t &EAX() const {return regs[0];} 
    const uint32_t &EBX() const {return regs[1];} 
    const uint32_t &ECX() const {return regs[2];} 
    const uint32_t &EDX() const {return regs[3];} 
}; 

#endif // CPUID_H 

Để sử dụng nó chỉ cần nhanh chóng một thể hiện của lớp, nạp CPUID hướng dẫn bạn quan tâm và kiểm tra sổ đăng ký. Ví dụ:

#include "CPUID.h" 

#include <iostream> 
#include <string> 

using namespace std; 

int main(int argc, char *argv[]) { 
    CPUID cpuID(0); // Get CPU vendor 

    string vendor; 
    vendor += string((const char *)&cpuID.EBX(), 4); 
    vendor += string((const char *)&cpuID.EDX(), 4); 
    vendor += string((const char *)&cpuID.ECX(), 4); 

    cout << "CPU vendor = " << vendor << endl; 

    return 0; 
} 

trang Wikipedia này sẽ cho bạn biết làm thế nào để sử dụng CPUID: http://en.wikipedia.org/wiki/CPUID

EDIT: Added #include <intrin.h> cho Windows, mỗi ý kiến.

+4

Câu trả lời hay. Chỉ cần lưu ý: bạn cần phải bao gồm '#include ' trên Windows để sử dụng hàm __cpuid(). –

+1

Đó là một rủi ro rất nhỏ và dễ sửa, nhưng bạn cũng quên '#include '; 3 – Gurgadurgen

+0

@Gurgadurgen '' '' '' được bao gồm bởi '' '' '' trên hầu hết các hệ thống nhưng ok, Tôi sẽ thêm nó. – jcoffland

1

Có thể không chính xác những gì bạn đang tìm kiếm, nhưng Intel có good article and sample code để liệt kê các kiến ​​trúc nền tảng 64 bit của Intel (bộ xử lý, bộ nhớ cache, v.v.) cũng bao gồm bộ xử lý 32 bit x86.

+0

tôi thấy được việc này đã , có một số chi tiết về intel.com cũng như MSDN. Nhưng đặc biệt đối với người mà bạn tham chiếu: cho cuộc sống của tôi, tôi sẽ không thể tìm ra cách biên dịch nó thành một số dll riêng mà tôi có thể gọi từ mã C# của mình ... Tôi đang bận học mọi thứ lập trình vượt ra ngoài môi trường được quản lý, nhưng các đường cong học tập đang dốc lên) – Kris

+2

IA64 thực sự là Itanium, trong khi bài viết đó đề cập đến "Intel 64" thường được gọi là x86_64. – kdt

+1

Intel 64 tương ứng với AMD64, không phải IA64 là Itanium –

6

Xem this MSDN article about __cpuid.

Có một mẫu toàn diện biên dịch với Visual Studio 2005 trở lên. Cho Visual Studio 6, bạn có thể sử dụng thay vì trình biên dịch __cpuid instrinsic:

void __cpuid(int CPUInfo[4], int InfoType) 
{ 
__asm 
    { 
    mov esi, CPUInfo 
    mov eax, InfoType 
    xor ecx, ecx 
    cpuid 
    mov dword ptr [esi + 0], eax 
    mov dword ptr [esi + 4], ebx 
    mov dword ptr [esi + 8], ecx 
    mov dword ptr [esi + 12], edx 
    } 
} 

cho Visual Studio 2005, bạn có thể sử dụng thay vì trình biên dịch __cpuidex instrinsic:

void __cpuidex(int CPUInfo[4], int InfoType, int ECXValue) 
{ 
__asm 
    { 
    mov esi, CPUInfo 
    mov eax, InfoType 
    mov ecx, ECXValue 
    cpuid 
    mov dword ptr [esi + 0], eax 
    mov dword ptr [esi + 4], ebx 
    mov dword ptr [esi + 8], ecx 
    mov dword ptr [esi + 12], edx 
    } 
} 
+3

Xác định '__cpuid' và' __cpuidex' là kết quả của hành vi không xác định vì các số nhận dạng được đặt trước. – rightfold