標籤:des style http color io ar 使用 sp 資料
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */#include <ngx_config.h>#include <ngx_core.h>// 如果 CPU 架構是 i386 或 amd64,並且編譯器是 GNU Compiler 或 Intel Compiler,則定義 cngx_puid 函數// 否則 ngx_cpuid 函數為空白#if (( __i386__ || __amd64__ ) && ( __GNUC__ || __INTEL_COMPILER ))static ngx_inline void ngx_cpuid(uint32_t i, uint32_t *buf);// i386 架構的 CPU,調用 CPU 指令 cpuid,擷取 CPU 相關資訊#if ( __i386__ )static ngx_inline voidngx_cpuid(uint32_t i, uint32_t *buf){ /* * we could not use %ebx as output parameter if gcc builds PIC, * and we could not save %ebx on stack, because %esp is used, * when the -fomit-frame-pointer optimization is specified. */ __asm__ ( " mov %%ebx, %%esi; " " cpuid; " " mov %%eax, (%1); " " mov %%ebx, 4(%1); " " mov %%edx, 8(%1); " " mov %%ecx, 12(%1); " " mov %%esi, %%ebx; " : : "a" (i), "D" (buf) : "ecx", "edx", "esi", "memory" );}// amd64 架構的 CPU,調用 CPU 指令 cpuid,擷取 CPU 相關資訊#else /* __amd64__ */static ngx_inline voidngx_cpuid(uint32_t i, uint32_t *buf){ uint32_t eax, ebx, ecx, edx; // 內聯彙編,可以參見我此前的兩篇博文 // 《GCC內聯彙編(1)Get started》 // 《GCC內聯彙編(2)GCC產生彙編代碼簡單一實例》 __asm__ ( "cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "a" (i) ); // 傳回值在四個通用寄存器中,賦給 buf,又外部調用處使用 buf[0] = eax; buf[1] = ebx; buf[2] = edx; buf[3] = ecx;}#endif/* auto detect the L2 cache line size of modern and widespread CPUs */voidngx_cpuinfo(void){ // 儲存廠商識別串,即 Vendor ID u_char *vendor; // vbuf 作為 EAX=0 時擷取到的資料的 buffer // cpu 作為 EAX=1 時擷取到的 CPU 說明 // model 為後面根據 CPU 說明中的 Extended Model 和 Model 計算出來的值 uint32_t vbuf[5], cpu[4], model; vbuf[0] = 0; vbuf[1] = 0; vbuf[2] = 0; vbuf[3] = 0; vbuf[4] = 0; // cpuid 第0號功能(EAX=0),擷取最大功能號和廠商識別串 // vbuf[0] 儲存最大功能號 // vbuf[1], vbuf[2], vbuf[3] 儲存廠商識別號 ngx_cpuid(0, vbuf); vendor = (u_char *) &vbuf[1]; if (vbuf[0] == 0) { return; } // cpuid 第1號功能(EAX=1),擷取 CPU 說明 // 3:0 - Stepping // 7:4 - Model // 11:8 - Family // 13:12 - Processor Type // 19:16 - Extended Model // 27:20 - Extended Family ngx_cpuid(1, cpu); // 如果廠商識別號為 Intel 的 if (ngx_strcmp(vendor, "GenuineIntel") == 0) { // 根據 Intel CPU 的家族號來 switch switch ((cpu[0] & 0xf00) >> 8) { /* Pentium */ case 5: ngx_cacheline_size = 32; break; /* Pentium Pro, II, III */ case 6: // cacheline 是 32 ngx_cacheline_size = 32; // 根據 Extended Model 和 Model,來確定該情況下的 cacheline // 比如 Extended Model 為 0x1,Model 為 0xd,則 model 變數值為 0x1d0,大於 0xd0,滿足 if // 比如 Extended Model 為 0x0,Model 為 0xd,則 model 變數值為 0x0d0,等於 0xd0,滿足 if // 比如 Extended Model 為 0x0,Model 為 0xc,則 model 變數值為 0x0c0,小於 0xd0,不滿足 if model = ((cpu[0] & 0xf0000) >> 8) | (cpu[0] & 0xf0); if (model >= 0xd0) { /* Intel Core, Core 2, Atom */ ngx_cacheline_size = 64; } break; /* * Pentium 4, although its cache line size is 64 bytes, * it prefetches up to two cache lines during memory read */ // cacheline 也是 64 位元,只不過在讀記憶體預取資料時會取兩倍 cacheline 長度的東東 case 15: ngx_cacheline_size = 128; break; } // 如果廠商識別號為 AMD 的 } else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) { ngx_cacheline_size = 64; }}#elsevoidngx_cpuinfo(void){}#endif
Reference
- CPUID - Wikipedia
Nginx源碼完全注釋(5)core/ngx_cpuinfo.c