Pour clôturer cette série de billets (lire les billets 1/3 et 2/3), je vais vous présenter rapidement une dernière méthode pour obtenir les caractéristiques du processeur (CPU) de votre machine.
Les méthodes présentées jusqu’à présent étaient soient incomplètes (voire incorrectes), soient différentes selon le système d’exploitation. Afin de corriger ces problèmes, nous allons utiliser une méthode très proche du CPU. Pour ce faire nous allons utiliser le langage assembleur et l’opcode CPUID.
Pour l’utiliser sous MATLAB, il est nécessaire de l’inclure dans un fichier MEX. Je vous propose donc deux versions écrites en C selon que vous utilisez les compilateurs Microsoft Visual C++ ou GNU gcc.
Voici le code pour gcc :
#include <string.h>
void cpuid(int b[4], int a) {
__asm( "cpuid"
: "=a" (b[0]), "=b" (b[1]), "=c" (b[2]), "=d" (b[3])
: "a" (a));
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] ) {
int CPUInfo[4] = {-1};
char CPUString[0x20];
const mwSize dims[2] = {1,5};
cpuid(CPUInfo, 0);
memset(CPUString, 0, sizeof(CPUString));
*((int*)CPUString) = CPUInfo[1];
*((int*)(CPUString+4)) = CPUInfo[3];
*((int*)(CPUString+8)) = CPUInfo[2];
plhs[0] = mxCreateCellArray(2, dims);
mxSetCell(plhs[0], 4, mxCreateString(CPUString));
cpuid(CPUInfo, 1);
mxSetCell(plhs[0], 0, mxCreateDoubleScalar((double)((CPUInfo[0] >> 8) & 0xf)));
mxSetCell(plhs[0], 1, mxCreateDoubleScalar((double)((CPUInfo[0] >> 16) & 0xf)));
mxSetCell(plhs[0], 2, mxCreateDoubleScalar((double)((CPUInfo[0] >> 4) & 0xf)));
mxSetCell(plhs[0], 3, mxCreateDoubleScalar((double)(CPUInfo[0] & 0xf)));
}
et le « même » pour Visual C++ :
#include <string.h>
#include <intrin.h>
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] ) {
int CPUInfo[4] = {-1};
char CPUString[0x20];
const mwSize dims[2] = {1,5};
__cpuid(CPUInfo, 0);
memset(CPUString, 0, sizeof(CPUString));
*((int*)CPUString) = CPUInfo[1];
*((int*)(CPUString+4)) = CPUInfo[3];
*((int*)(CPUString+8)) = CPUInfo[2];
plhs[0] = mxCreateCellArray(2, dims);
mxSetCell(plhs[0], 4, mxCreateString(CPUString));
__cpuid(CPUInfo, 1);
mxSetCell(plhs[0], 0, mxCreateDoubleScalar((double)((CPUInfo[0] >> 8) & 0xf)));
mxSetCell(plhs[0], 1, mxCreateDoubleScalar((double)((CPUInfo[0] >> 16) & 0xf)));
mxSetCell(plhs[0], 2, mxCreateDoubleScalar((double)((CPUInfo[0] >> 4) & 0xf)));
mxSetCell(plhs[0], 3, mxCreateDoubleScalar((double)(CPUInfo[0] & 0xf)));
}
A compiler comme ceci sous MATLAB :
Vous pourrez ensuite l’utiliser sous MATLAB comme ceci :
fprintf('Family %d Extended Model %d Model %d Stepping %d, %s\n', ...
data{1},data{2},data{3},data{4},strtrim(data{5}));
Ce qui renvoie bien les bonnes valeurs sur ma machine comme nous l’avons vu dans le billet précédent :
On peut ensuite appliquer la méthodologie décrite dans les précédents billets pour retrouver le CPU dans les fiches constructeurs.
Dans le même esprit, voici un autre code pour récupérer la désignation commerciale du CPU.
Avec gcc :
#include <string.h>
void cpuid(int b[4], int a) {
__asm( "cpuid"
: "=a" (b[0]), "=b" (b[1]), "=c" (b[2]), "=d" (b[3])
: "a" (a));
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] ) {
int CPUInfo[4] = {-1};
char CPUBrandString[0x40];
cpuid(CPUInfo, 0x80000000);
memset(CPUBrandString, 0, sizeof(CPUBrandString));
cpuid(CPUInfo, 0x80000002);
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
cpuid(CPUInfo, 0x80000003);
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
cpuid(CPUInfo, 0x80000004);
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
plhs[0] = mxCreateString(CPUBrandString);
}
Sous Visual C++ :
#include <string.h>
#include <intrin.h>
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] ) {
int CPUInfo[4] = {-1};
char CPUBrandString[0x40];
__cpuid(CPUInfo, 0x80000000);
memset(CPUBrandString, 0, sizeof(CPUBrandString));
__cpuid(CPUInfo, 0x80000002);
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
__cpuid(CPUInfo, 0x80000003);
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
__cpuid(CPUInfo, 0x80000004);
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
plhs[0] = mxCreateString(CPUBrandString);
}
Une fois compilé, ce code me renvoi bien la bonne désignation du CPU de ma machine :
cpuname =
Intel(R) Core(TM) i5-2430M CPU @ 2.40GHz
Voila, vous avez maintenant la possibilité d’identifier le CPU de votre machine sous MATLAB grâce à plusieurs méthodes.
Vous trouverez les fichiers MEX compilés (Windows, Linux et Mac) de getcpubrandstring ici.
Vous trouverez les fichiers sources C-MEX utilisés dans cet article ici.
Si vous voulez aller plus loin dans l’exploration des caractéristiques du CPU de votre machine, voici quelques liens utiles :
- CPUID (Wikipedia)
- Déterminer le CPUID (Developpez.com)
- __cpuid (MSDN Library)
- CPUID (OSDev.org)
PS : les solutions proposées dans ce billet supposent que le CPU de votre machine connait les instructions CPUID (ce qui est le cas pour les processeurs Intel et AMD les plus couramment utilisés).