/*
* 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 void
ngx_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 void
ngx_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 */ void
ngx_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;
}
} #else void
ngx_cpuinfo(void)
{
} #endif

Reference

  1. CPUID - Wikipedia

Nginx源码完全注释(5)core/ngx_cpuinfo.c的更多相关文章

  1. Nginx源码完全注释(6)core/murmurhash

    下面是摘自 Google Code 的 Murmurhash 开源项目主页上的 Murmurhash2,Nginx 就是采用的这个. uint32_t MurmurHash2 ( const void ...

  2. Nginx 源码完全注释(11)ngx_spinlock

    Nginx 是多进程模式的,一个 master 与多个 workers,一般工作在多核 CPU 上,所以自旋锁就是必须用到的.Nginx 中的自旋锁的定义,位于 ngx_spinlock.c 中,如下 ...

  3. Nginx 源码完全注释(10)ngx_radix_tree

    ngx_radix_tree.h // 未被使用的节点 #define NGX_RADIX_NO_VALUE (uintptr_t) -1 typedef struct ngx_radix_node_ ...

  4. Nginx源码完全注释(9)nginx.c: ngx_get_options

    本文分析 ngxin.c 中的 ngx_get_options 函数,其影响: nginx.c 中的: static ngx_uint_t ngx_show_help; static ngx_uint ...

  5. Nginx源码完全注释(8)ngx_errno.c

    errno.h中的strerror(int errno)可以确定指定的errno的错误的提示信息.在 Nginx 中,将所有错误提示信息预先存储在一个数组里,而预先确定这个数组的大小,是在自动化脚本中 ...

  6. Nginx源码完全注释(2)ngx_array.h / ngx_array.c

    数组头文件 ngx_array.h #include <ngx_config.h> #include <ngx_core.h> struct ngx_array_s { voi ...

  7. nginx源码完全注释(1)ngx_alloc.h / ngx_alloc.c

    首先看 ngx_alloc.h 文件,主要声明或宏定义了 ngx_alloc,ngx_calloc,ngx_memalign,ngx_free. /* * Copyright (C) Igor Sys ...

  8. Nginx源码完全注释(7)ngx_palloc.h/ngx_palloc.c

    ngx_palloc.h /* * NGX_MAX_ALLOC_FROM_POOL should be (ngx_pagesize - 1), i.e. 4095 on x86. * On Windo ...

  9. Nginx源码完全注释(4)ngx_queue.h / ngx_queue.c

    队列头文件ngx_queue.h #include <ngx_config.h> #include <ngx_core.h> #ifndef _NGX_QUEUE_H_INCL ...

随机推荐

  1. UML基本架构建模--类的术语和概念

     Terms and Concepts 术语和概念   A classis a description of a set of objects that share the same attrib ...

  2. virtual之虚函数,虚继承

    当类中包含虚函数时,则该类每个对象中在内存分配中除去数据外还包含了一个虚函数表指针(vfptr),指向虚函数表(vftable),虚函数表中存放了该类包含的虚函数的地址. 当子类通过虚继承的方式从父类 ...

  3. piezo film 压电相关信息记录 (2018-05-04 更新)

    piezo film 压电相关信息记录 起因需要使用 Piezo 做一些设计 http://www.te.com.cn/chn-zh/videos/transportation/piezo-film- ...

  4. 微软Azure平台 cloud service动态申请证书并绑定证书碰到的坑

    我们有一个saas平台 部分在azure的cloud service 使用lets encrypt来申请证书.每一个商家申请域名之后就需要通过Lets encrypt来得到证书并绑定证书. 主要碰到的 ...

  5. Java Array 方法和使用

    1.Arrays.toString():数组转字符串 格式:Arrays.toString(数组名) 将数组转化成字符串,此时输出的结果是字符串类型. import java.util.Arrays; ...

  6. json工具性能比较:json-lib和jackson进行Java对象到json字符串序列化[转]

    网上查找“java json”,发现大家使用最多的还是json-lib来进行java对象的序列化成json对象和反序列化成java对象的操作.但是之前在网上也看到过一往篇关于json序列化性能比较的文 ...

  7. Type-C潮流下 如何衡量一款数据线好坏?

    不少新一代手机开始支持Type-C接口,比如乐视.PPTV.努比亚Z11.小米4C和三星Note7等.和普通Micro USB相比,Type-C数据线因为正反插的关系对品质要求更高,不然随时有短路烧毁 ...

  8. node的socket.io的之事件篇

    socket.io类库不但可以相互发送消息,而且还可以通过socket端口对象的emit方法互相发送事件. emit在之前的事件上说过现在一句话带过:emit是用来手动触发事件的. socket.em ...

  9. Druid.io系列(四):索引过程分析

    原文链接: https://blog.csdn.net/njpjsoftdev/article/details/52956083 Druid底层不保存原始数据,而是借鉴了Apache Lucene.A ...

  10. java.lang.NoClassDefFoundError: org/jaxen/JaxenException解决方法

    在使用dom4j的xpath时出现java.lang.NoClassDefFoundError: org/jaxen/JaxenException的异常,原因是dom4j引用了jaxen jar包,而 ...