`
Poechant
  • 浏览: 229551 次
博客专栏
Bebe66e7-3a30-3fc9-aeea-cfa3b474b591
Nginx高性能Web服务...
浏览量:24321
5738817b-23a1-3a32-86de-632d7da73b1e
Cumulus实时媒体服务...
浏览量:22104
社区版块
存档分类
最新评论

Nginx源码完全注释(5)core/ngx_cpuinfo.c

 
阅读更多

Nginx源码完全注释(5)core/ngx_cpuinfo.c

  • 作者:柳大·Poechant(钟超)
  • 邮箱:zhongchao.ustc#gmail.com(# -> @)
  • 博客:Blog.CSDN.net/Poechant
  • 日期:August 18th, 2012

/*
 * 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

-

转载请注明来自柳大Poechant(钟超Michael)的CSDN博客:

钟超Michael的博客:Blog.CSDN.net/Poechant

钟超Michael的微博:钟超Michael的新浪微博

-

分享到:
评论

相关推荐

    Nginx的SQLite模块ngx_sqlite.zip

    ngx_sqlite 是嵌入 sqlite 数据库的 nginx 模块。通过强大的nginx server,可以使用http协议访问sqlite数据库。环境- sqlite 3- nginx-1.6.3 安装```sh $ git clone https://github.com/rryqszq4/ngx_sqlite.git...

    ngx_http_dav_ext_module.so

    ngx_http_dav_ext_module.so centos7 nginx 1.18 可以作为模块加载

    ngx_stream_module.so

    nginx1.20.2

    nginx 源代码 注释版

    9. **内存池**:Nginx使用内存池(`src/core/ngx_pool.c`和`src/core/ngx_slab.c`)来高效管理内存,避免频繁的内存分配和释放操作。 10. **日志系统**:`src/core/ngx_log.c`和`src/core/ngx_cycle.c`处理日志记录...

    嵌入Python脚本的Nginx模块ngx_python.zip

    ngx_python 是为 nginx 嵌入 python 脚本的模块。环境- python 2.7.*- nginx-1.6.3 安装```sh git clone https://github.com/rryqszq4/ngx_python.git wget 'http://nginx.org/download/nginx-1.6.3.tar.gz' ...

    nginx的php模块ngx_php.zip

    ngx_php功能是为nginx模块嵌入php脚本语言。别名为php-nginx-module。 特性 * 支持加载php.ini配置文件 * 支持原生php的全局变量$_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_SESSION... * 支持运行php代码...

    nginx-1.18.0-2.el7.ngx.x86-64.rpm安装包(含有部署手册)

    nginx-1.18.0-2.el7.ngx.x86_64.rpm安装包(含有部署手册) nginx-1.18.0-2.el7.ngx.x86_64.rpm安装包(含有部署手册) nginx-1.18.0-2.el7.ngx.x86_64.rpm安装包(含有部署手册) nginx-1.18.0-2.el7.ngx.x86_64.rpm...

    ngx_cache_purge_2.4.2.tar.gz

    ./configure --add-module=../ngx_cache_purge-2.4.2 ``` 4. 编译并安装Nginx,这将同时编译ngx_cache_purge模块。 5. 在Nginx的配置文件中启用该模块,并设置相应的清理规则,如: ``` http { cache_path /...

    ngx_http_proxy_connect_module.zip

    3. 编译和安装:运行`./configure`,然后`make`和`make install`以编译并安装带有新模块的Nginx。 4. 配置Nginx服务器块:在Nginx的配置文件(如nginx.conf)中,为需要启用代理服务的域或端口定义一个新的服务器块...

    lua-upstream-nginx-module, Nginx C 模块将Lua向ngx_lua公开,用于 Nginx upstreams.zip

    lua-upstream-nginx-module, Nginx C 模块将Lua向ngx_lua公开,用于 Nginx upstreams 电子邮件名称ngx_http_lua_upstream - Nginx MODULE,用于向 Nginx upstreams公开Lua到 ngx_lua目录NAME状态概要说明函数get_...

    ngx_devel_kit-0.3.0

    ngx_devel_kit(通常缩写为 NDK)是一个针对Nginx的模块开发工具集,它为构建自定义Nginx模块提供了便利。在Nginx生态系统中,NDK是一个重要的扩展工具,允许开发者利用C语言直接操作Nginx的内部结构,以实现更高级...

    reading-code-of-nginx-1.9.2_y123456yz.tar.gz

    学习Nginx源码,首先需要熟悉C语言和网络编程基础,然后从主进程和工作进程的入口函数开始,逐步了解各个模块的功能和相互之间的协作。同时,结合实际运行的网络请求,观察源码中的数据结构变化和控制流程,能够更好...

    nginx1.9.2源代码(内含大量注释的版本).zip

    在 `src/core/ngx_event.h` 和 `src/event/ngx_event.c` 中,可以研究 Nginx 如何高效地处理网络事件。 **3. 多进程与多线程** Nginx 通常采用主进程+工作进程的模式,主进程负责管理工作进程和配置加载,工作进程...

    ngx_http_subrange_module.zip

    当Nginx作为文件下载服务的反向代理,用户请求一个非常大的文件的时候,它会一直占满反向代理服务器与后端主机之间的带宽。因为nginx一次获取整个文件,缓冲获取到的文件,导致客户端不能马上读取到。带宽使用和iowait会...

    nginx-1.21.6-1.el7-rtmp.ngx.x86_64.tar.gz

    **Nginx 1.21.6 with RTMP 模块详解** Nginx 是一款高性能、轻量级的 Web 服务器/反向代理服务器,广泛应用于网站部署、负载均衡以及流媒体服务等领域。本资源提供的 "nginx-1.21.6-1.el7-rtmp.ngx.x86_64.tar.gz" ...

    lua-nginx-module-0.10.9rc7

    ngx_devel_kit(简称ndk)是一个用于开发Nginx模块的工具集,它提供了很多用于编写C语言扩展的便利函数。在0.10.9rc7这个版本中,可能需要特定的ndk版本才能确保所有功能正常运行。如果版本不匹配,可能会遇到如时间...

    ngixn正向https代理模块(透明代理)

    - 安装与配置:首先,你需要下载并编译Nginx源码,将`ngx_http_proxy_connect_module`模块添加到编译选项中。然后,在Nginx的配置文件中启用该模块,配置代理规则,如设置监听端口、指定目标服务器等。 3. 配置...

    Linux Centos7.5 安装FastDFS所需软件

    2. **Glibc-devel**:C库的开发头文件,对于编译FastDFS源码是必要的。 3. **Openssl**:FastDFS使用SSL加密连接,需要openssl库。 4. **Nginx**:FastDFS可以通过Nginx作为反向代理,提供HTTP访问。 安装这些依赖...

    lua-nginx-module-0.10.13

    Lua-Nginx-Module,简称lua-nginx-module,是Nginx服务器的一个重要扩展模块,它将强大的Lua脚本语言集成到Nginx中,允许用户在Nginx配置文件中直接编写Lua代码,极大地增强了Nginx的功能性和灵活性。版本0.10.13是...

    ngx_devel_kit-0.2.19.tar.gz

    4. 使用Nginx的configure脚本,通过指定--add-module选项添加NDK模块,例如:`./configure --add-module=路径/ngx_devel_kit-0.2.19`。 5. 编译并安装Nginx:`make && make install`。 6. 更新Nginx配置文件,启用...

Global site tag (gtag.js) - Google Analytics