void cpuid_basic_identify(processor_info_t *pc) { struct cpu_raw_data_t raw; cpuid_get_raw_data(&raw); memcpy(raw.vendor_str + 0, &raw.basic_cpuid[0][1], 4); memcpy(raw.vendor_str + 4, &raw.basic_cpuid[0][3], 4); memcpy(raw.vendor_str + 8, &raw.basic_cpuid[0][2], 4); raw.vendor_str[12] = 0; pc->avx_level = 0; pc->sse_level = 0; if (strcmp(raw.vendor_str, "GenuineIntel") == 0) { pc->proc_type = PROC_X64_INTEL; pc->sse_level = 2; } else if (strcmp(raw.vendor_str, "AuthenticAMD") == 0) { pc->proc_type = PROC_X64_AMD; pc->sse_level = 2; } if (raw.basic_cpuid[0][0] >= 1) { // ECX has SSE 4.2 and AVX flags // Bit 20 is SSE 4.2 and bit 28 indicates AVX if (raw.basic_cpuid[1][2] & (1 << 20)) { pc->sse_level = 4; } else { pc->sse_level = 3; } pc->avx_level = 0; if (raw.basic_cpuid[1][2] & (1 << 28)) { pc->avx_level = 1; } } }
void cpuid_basic_identify(processor_cap_t *pc) { struct cpu_raw_data_t raw; cpuid_get_raw_data(&raw); memcpy(raw.vendor_str + 0, &raw.basic_cpuid[0][1], 4); memcpy(raw.vendor_str + 4, &raw.basic_cpuid[0][3], 4); memcpy(raw.vendor_str + 8, &raw.basic_cpuid[0][2], 4); raw.vendor_str[12] = 0; pc->avx_level = 0; pc->sse_level = 0; pc->sse_sub_level = 0; pc->xop_avail = 0; if (strcmp(raw.vendor_str, "GenuineIntel") == 0) { pc->proc_type = PROC_X64_INTEL; pc->sse_level = 2; } else if (strcmp(raw.vendor_str, "AuthenticAMD") == 0) { pc->proc_type = PROC_X64_AMD; pc->sse_level = 2; } if (raw.basic_cpuid[0][0] >= 1) { // ECX has SSE 4.2 and AVX flags // Bit 20 is SSE 4.2 and bit 28 indicates AVX if (raw.basic_cpuid[1][2] & SSE4_1_FLAG) { pc->sse_level = 4; pc->sse_sub_level = 1; if (raw.basic_cpuid[1][2] & SSE4_2_FLAG) { pc->sse_sub_level = 2; } } else { if (raw.basic_cpuid[1][2] & SSE3_FLAG) { pc->sse_level = 3; if (raw.basic_cpuid[1][2] & SSSE3_FLAG) { pc->sse_sub_level = 1; } } else { pc->sse_level = 2; } } pc->avx_level = 0; if (raw.basic_cpuid[1][2] & AVX_FLAG) { pc->avx_level = 1; } if (raw.basic_cpuid[7][1] & AVX2_FLAG) { pc->avx_level = 2; } if (raw.basic_cpuid[1][2] & AES_FLAG) { pc->aes_avail = 1; } if (raw.ext_cpuid[1][2] & XOP_FLAG) { pc->xop_avail = 1; } } }
INTVAL Parrot_get_num_cpus(SHIM_INTERP) { INTVAL nprocs = -1; #ifdef _SC_NPROCESSORS_ONLN nprocs = sysconf(_SC_NPROCESSORS_ONLN); #elif defined(PARROT_HAS_HEADER_LIBCPUID) struct cpu_raw_data_t raw; struct cpu_id_t data; if (!cpuid_present()) { printf("cpuid_present failed\n"); exit(EXIT_FAILURE); } if (cpuid_get_raw_data(&raw) < 0) { printf("cpuid_get_raw_data failed\n"); printf("Error: %s\n", cpuid_error()); exit(EXIT_FAILURE); } if (cpu_identify(&raw, &data) < 0) { printf("cpu_identify failed\n"); printf("Error: %s\n", cpuid_error()); exit(EXIT_FAILURE); } nprocs = data.num_cores; #else FILE *f; char line[128]; if (!fopen("/proc/cpuinfo", "rb")) return nprocs; while (!feof(f)) { fgets(line, 128, f); if (strlen(line) == 1) continue; if (strncmp(line, "cpu cores", 8) == 0) { sscanf(line, "cpu cores\t: %d", &nprocs); fclose(f); return nprocs; } } fclose(f); #endif return nprocs; }
int main(int argc, char** argv) { int parseres = parse_cmdline(argc, argv); int i, readres, writeres; int only_clock_queries; struct cpu_raw_data_t raw; struct cpu_id_t data; if (parseres != 1) return parseres; /* In quiet mode, disable libcpuid warning messages: */ if (need_quiet) cpuid_set_warn_function(NULL); cpuid_set_verbosiness_level(verbose_level); /* Redirect output, if necessary: */ if (strcmp(out_file, "") && strcmp(out_file, "-")) { fout = fopen(out_file, "wt"); if (!fout) { if (!need_quiet) fprintf(stderr, "Cannot open `%s' for writing!\n", out_file); return -1; } atexit(close_out); } else { fout = stdout; } /* If requested, print library version: */ if (need_version) fprintf(fout, "%s\n", cpuid_lib_version()); if (need_input) { /* We have a request to input raw CPUID data from file: */ if (!strcmp(raw_data_file, "-")) /* Input from stdin */ readres = cpuid_deserialize_raw_data(&raw, ""); else /* Input from file */ readres = cpuid_deserialize_raw_data(&raw, raw_data_file); if (readres < 0) { if (!need_quiet) { fprintf(stderr, "Cannot deserialize raw data from "); if (!strcmp(raw_data_file, "-")) fprintf(stderr, "stdin\n"); else fprintf(stderr, "file `%s'\n", raw_data_file); /* Print the error message */ fprintf(stderr, "Error: %s\n", cpuid_error()); } return -1; } } else { if (check_need_raw_data()) { /* Try to obtain raw CPUID data from the CPU: */ readres = cpuid_get_raw_data(&raw); if (readres < 0) { if (!need_quiet) { fprintf(stderr, "Cannot obtain raw CPU data!\n"); fprintf(stderr, "Error: %s\n", cpuid_error()); } return -1; } } } /* Need to dump raw CPUID data to file: */ if (need_output) { if (verbose_level >= 1) printf("Writing raw CPUID dump to `%s'\n", raw_data_file); if (!strcmp(raw_data_file, "-")) /* Serialize to stdout */ writeres = cpuid_serialize_raw_data(&raw, ""); else /* Serialize to file */ writeres = cpuid_serialize_raw_data(&raw, raw_data_file); if (writeres < 0) { if (!need_quiet) { fprintf(stderr, "Cannot serialize raw data to "); if (!strcmp(raw_data_file, "-")) fprintf(stderr, "stdout\n"); else fprintf(stderr, "file `%s'\n", raw_data_file); /* Print the error message */ fprintf(stderr, "Error: %s\n", cpuid_error()); } return -1; } } if (need_report) { if (verbose_level >= 1) { printf("Writing decoded CPU report to `%s'\n", out_file); } /* Write a thorough report of cpu_id_t structure to output (usually stdout) */ fprintf(fout, "CPUID is present\n"); /* * Try CPU identification * (this fill the `data' structure with decoded CPU features) */ if (cpu_identify(&raw, &data) < 0) fprintf(fout, "Error identifying the CPU: %s\n", cpuid_error()); /* OK, now write what we have in `data'...: */ fprintf(fout, "CPU Info:\n------------------\n"); fprintf(fout, " vendor_str : `%s'\n", data.vendor_str); fprintf(fout, " vendor id : %d\n", (int) data.vendor); fprintf(fout, " brand_str : `%s'\n", data.brand_str); fprintf(fout, " family : %d (%02Xh)\n", data.family, data.family); fprintf(fout, " model : %d (%02Xh)\n", data.model, data.model); fprintf(fout, " stepping : %d (%02Xh)\n", data.stepping, data.stepping); fprintf(fout, " ext_family : %d (%02Xh)\n", data.ext_family, data.ext_family); fprintf(fout, " ext_model : %d (%02Xh)\n", data.ext_model, data.ext_model); fprintf(fout, " num_cores : %d\n", data.num_cores); fprintf(fout, " num_logical: %d\n", data.num_logical_cpus); fprintf(fout, " tot_logical: %d\n", data.total_logical_cpus); fprintf(fout, " L1 D cache : %d KB\n", data.l1_data_cache); fprintf(fout, " L1 I cache : %d KB\n", data.l1_instruction_cache); fprintf(fout, " L2 cache : %d KB\n", data.l2_cache); fprintf(fout, " L3 cache : %d KB\n", data.l3_cache); fprintf(fout, " L4 cache : %d KB\n", data.l4_cache); fprintf(fout, " L1D assoc. : %d-way\n", data.l1_assoc); fprintf(fout, " L2 assoc. : %d-way\n", data.l2_assoc); fprintf(fout, " L3 assoc. : %d-way\n", data.l3_assoc); fprintf(fout, " L4 assoc. : %d-way\n", data.l4_assoc); fprintf(fout, " L1D line sz: %d bytes\n", data.l1_cacheline); fprintf(fout, " L2 line sz : %d bytes\n", data.l2_cacheline); fprintf(fout, " L3 line sz : %d bytes\n", data.l3_cacheline); fprintf(fout, " L4 line sz : %d bytes\n", data.l4_cacheline); fprintf(fout, " SSE units : %d bits (%s)\n", data.sse_size, data.detection_hints[CPU_HINT_SSE_SIZE_AUTH] ? "authoritative" : "non-authoritative"); fprintf(fout, " code name : `%s'\n", data.cpu_codename); fprintf(fout, " features :"); /* * Here we enumerate all CPU feature bits, and when a feature * is present output its name: */ for (i = 0; i < NUM_CPU_FEATURES; i++) if (data.flags[i]) fprintf(fout, " %s", cpu_feature_str(i)); fprintf(fout, "\n"); /* Is CPU clock info requested? */ if (need_clockreport) { if (need_timed_clockreport) { /* Here we use the RDTSC-based routine */ fprintf(fout, " cpu clock : %d MHz\n", cpu_clock_measure(400, 1)); } else { /* Here we use the OS-provided info */ fprintf(fout, " cpu clock : %d MHz\n", cpu_clock()); } } } /* * Check if we have any queries to process. * We have to handle the case when `--clock' or `--clock-rdtsc' options * are present. * If in report mode, this will generate spurious output after the * report, if not handled explicitly. */ only_clock_queries = 1; for (i = 0; i < num_requests; i++) if (requests[i] != NEED_CLOCK && requests[i] != NEED_CLOCK_RDTSC) { only_clock_queries = 0; break; } /* OK, process all queries. */ if ((!need_report || !only_clock_queries) && num_requests > 0) { /* Identify the CPU. Make it do cpuid_get_raw_data() itself */ if (check_need_raw_data() && cpu_identify(&raw, &data) < 0) { if (!need_quiet) fprintf(stderr, "Error identifying the CPU: %s\n", cpuid_error()); return -1; } for (i = 0; i < num_requests; i++) print_info(requests[i], &raw, &data); } if (need_cpulist) { print_cpulist(); } return 0; }