Author Topic: New cpuId() global PJSR function  (Read 1456 times)

Online Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 6949
    • View Profile
    • http://pixinsight.com/
New cpuId() global PJSR function
« on: 2014 May 02 11:10:08 »
Starting with build 1092 of the PixInsight Core application, the PixInsight JavaScript Runtime (PJSR) provides a new cpuId() global method:

[eax,ebx,ecx,edx] cpuId( unsigned info[, unsigned ecx=0] )

This method executes the CPUID machine instruction (CPU Identification), available on all Intel x86/x64 and compatible processors since the Pentium IV. The info argument is the value of the EAX register before executing the CPUID instruction. The optional ecx argument (which only works in the Windows version of PixInsight for now) is the initial value of the ECX register.

The CPUID instruction returns processor identification and feature information in the EAX, EBX, ECX and EDX registers which, as indicated by the metadescription above, are returned by the cpuId function as an array of four elements. For information on the data that can be obtained with this instruction, see this Wikipedia article. The most complete reference is Intel's reference documentation.

I have implemented this function because it is necessary for the official PixInsight benchmark scripts that we plan on releasing during the incoming weeks. As an example of use, here is a little script that prints some information on the running processor on the console:

Code: [Select]
/*
 * CPU Identification Utility
 *
 * References:
 *
 *    Intel® 64 and IA-32 Architectures Software Developer’s Manual /
 *    Volume 2A: Instruction Set Reference, A-M, 3-157
 *
 * Copyright (C) Pleiades Astrophoto S.L. All Rights Reserved.
 * Written by Juan Conejero, PTeam, May 2014.
 */
function CPUId()
{
   this.id = function( eax )
   {
      var r = cpuId( eax );
      this.eax = r[0];
      this.ebx = r[1];
      this.ecx = r[2];
      this.edx = r[3];
   };

   this.vendor = function()
   {
      this.id( 0 );
      return (this.registerToASCII( this.ebx ) +
              this.registerToASCII( this.edx ) +
              this.registerToASCII( this.ecx )).trim();
   };

   this.processorBrand = function()
   {
      this.id( 0x80000000 );
      if ( this.eax < 0x80000004 )
         throw "Unsupported function";
      var s;
      this.id( 0x80000002 );
      s =  this.registerToASCII( this.eax ) +
           this.registerToASCII( this.ebx ) +
           this.registerToASCII( this.ecx ) +
           this.registerToASCII( this.edx );
      this.id( 0x80000003 );
      s += this.registerToASCII( this.eax ) +
           this.registerToASCII( this.ebx ) +
           this.registerToASCII( this.ecx ) +
           this.registerToASCII( this.edx );
      this.id( 0x80000004 );
      s += this.registerToASCII( this.eax ) +
           this.registerToASCII( this.ebx ) +
           this.registerToASCII( this.ecx ) +
           this.registerToASCII( this.edx );
      return s.trim();
   };

   this.processorFeatures = function()
   {
      this.id( 0x80000000 );
      if ( this.eax < 0x80000001 )
         throw "Unsupported function";

      var edxBits = [
         "fpu", "vme", "de", "pse",
         "tsc", "msr", "pae", "mce",
         "cx8", "apic", "", "sep",
         "mtrr", "pge", "mca", "cmov",
         "pat", "pse36", "psn", "clfsh",
         "", "ds", "acpi", "mmx",
         "fxsr", "sse", "sse2", "ss",
         "htt", "tm", "", "pbe"
      ];

      var ecxBits = [
         "sse3", "pclmulqdq", "dtes64", "monitor",
         "ds-cpl", "vmx", "smx", "est",
         "tm2", "ssse3", "cnxt-id", "sdbg",
         "fma", "cmpxchg16b", "xtpr", "pdcm",
         "", "pcid", "dca", "sse4.1",
         "sse4.2", "x2apic", "movbe", "popcnt",
         "tsc-deadline", "aes", "xsave", "osxsave",
         "avx", "f16c", "rdrand", ""
      ];

      this.id( 1 );
      var s = "";
      var n = 0;
      for ( var i = 0; i < 32; ++i )
         if ( edxBits[i].length > 0 )
            if ( this.edx & (1 << i) )
            {
               if ( n++ )
                  s += ' ';
               s += edxBits[i];
            }
      for ( var i = 0; i < 32; ++i )
         if ( ecxBits[i].length > 0 )
            if ( this.ecx & (1 << i) )
            {
               if ( n++ )
                  s += ' ';
               s += ecxBits[i];
            }
      return s;
   };

   this.registerToASCII = function( r )
   {
      return String.fromCharCode( (r & 0x000000ff),
                                  (r & 0x0000ff00) >>  8,
                                  (r & 0x00ff0000) >> 16,
                                  (r & 0xff000000) >> 24 );
   };
}

var cpu = new CPUId;

console.writeln( "<end><cbr><br><b>CPU Information</b>" );
console.writeln( "Vendor       : ", cpu.vendor() );
console.writeln( "Brand string : ", cpu.processorBrand() );
console.writeln( "Features     : ", cpu.processorFeatures() );

For example, after running this script on the workstation where I'm writing this post, I get the following output:

CPU Information
Vendor       : GenuineIntel
Brand string : Intel(R) Xeon(R) CPU E5-2695 v2 @ 2.40GHz
Features     : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clfsh ds acpi mmx fxsr sse sse2 ss htt tm pbe sse3 pclmulqdq dtes64 monitor ds-cpl vmx smx est tm2 ssse3 cmpxchg16b xtpr pdcm pcid dca sse4.1 sse4.2 x2apic popcnt tsc-deadline aes xsave osxsave avx f16c rdrand

Juan Conejero
PixInsight Development Team
http://pixinsight.com/