跳转至

笔记

Perf

简介

  • pref
  • kperf : ./kperf_static --pid 1043785 --topdown --cache --tlb --imix --uncore --duration 3 --iter-num 1

Intel SDM(Software Developer's Manual)

Introduction

This set consists of

volume Descriptions pages(size)
volume 1 Basic Architecture 500 pages(3MB)
volume 2 (combined 2A, 2B, 2C, and 2D) full instruction set reference 2522 pages(10.8MB)
volume 3 (combined 3A, 3B, 3C, and 3D) system programming guide 1534 pages(8.5MB)
volume 4 MODEL-SPECIFIC REGISTERS (MSRS) 520 pages

volume3: Memory management(paging), protection, task management, interrupt and exception handling, multi-processor support, thermal and power management features, debugging, performance monitoring, system management mode, virtual machine extensions (VMX) instructions, Intel® Virtualization Technology (Intel® VT), and Intel® Software Guard Extensions (Intel® SGX).

AMD64 Architecture Programmer's Manual (3336 pages)

more graph and easier to read.

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。

https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html

Make

导言

虽然大型项目会使用cmake,手写makefile的情况比较少,但是基本语法还是要熟悉的。

LinuxCommand: system info

时间

CST

CST 也可以指 中国标准时间(China Standard Time),UTC+8。这是中国的法定时区,没有夏令时调整。

date +"%Y-%m-%d %H:%M:%S %Z %:z

  • %Z 显示时区缩写(如 CST)。
  • %:z 显示时区偏移量(如 +08:00、-06:00)。

修改时间

timedatectl 是一个管理日期和时间的工具,可以用来永久设置系统时间和时区。

sudo timedatectl set-time "2024-10-26 19:12:19"

修改时区

如果发现时区也不正确,可以用下面的命令设置时区:

sudo timedatectl set-timezone "Asia/Shanghai"

例如,将时区设置为中国标准时间 (CST, UTC+8),时区名称需要使用 timedatectl list-timezones 查看可用的时区列表。

硬盘/挂载空间

df -h .

各个文件夹空间

deep为1

du -h -d .

进程查看与kill

# thi
ps aux | grep 1499321
ps -auxf | grep -nB 10 -E 'python[3]?|PID'
kill -9 

ps aux linux command whill show no zero cpu usage when the process is sleeping beacuse of its snapshots mechanism

apt-get problems

dpkg: 处理归档 /var/cache/apt/archives/bat_0.12.1-1build1_arm64.deb (--unpack)时出错:
 正试图覆盖 /usr/.crates2.json,它同时被包含于软件包 ripgrep 11.0.2-1build1
dpkg-deb: 错误: 粘贴 子进程被信号(断开的管道) 终止了
在处理时有错误发生:
 /var/cache/apt/archives/bat_0.12.1-1build1_arm64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
sudo apt-get purge -h
# jsonfile conflict purge - Remove packages and config files

tree

deep size

tree -L DepthSIze Folder_Path

so文件分析

#分析symbols 
nm -gDC intel64/gcc4.8/*
  • -g:显示全局符号表。
  • -D:显示动态符号表。
  • -C:将 C++ 符号名还原成源代码中的名称。

综合来看,使用 nm -gDC <filename> 命令可以查看一个二进制可执行文件或者共享库中的全局符号表和动态符号表,并将包含其中的 C++ 符号名还原成源代码中的名称。

shaojiemike@snode6 ~/github/gem5  [10:49:56]
> nm /usr/local/lib/libprotobuf.a |c++filt|grep google::protobuf::MessageFactory::InternalRegisterGeneratedFile
                 U google::protobuf::MessageFactory::InternalRegisterGeneratedFile(char const*, void (*)(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&))
0000000000000e00 T google::protobuf::MessageFactory::InternalRegisterGeneratedFile(char const*, void (*)(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&))

#分析子so
ldd .so

参考文献

Linux CMD

简介

  • 常用的linux命令行指令。
  • 包括少量实验数据的初步处理(bash脚本)和简单可视化(excel/echart)

Cpu Time

Situation

It is all started with two confusing situation.

  • I found out using ps aux | grep -v process_name, the process is in Sl+ state. But the cpu usage is not zero.
  • watch "ps aux |grep 3496617" always show the same cpu usage percentage, which is very confusing beacause htop always show up-down value. and pidstat -p 3516617 show cpu% less than 100%.

Git Standardization

workflow

内容模板

隐藏文件夹 .github , 里面放两个文件:

ISSUE_TEMPLATE.md

PULL_REQUEST_TEMPLATE.md

分支模型

Git Flow 分支模型

仓库有两个基础分支:

dev(默认分支)
master(用于发布)

通过pull request来合并新的代码:

协作者的代码通过pr合并到dev
dev通过pr合并到master

注意点:

merge 到 dev,使用squash merge
merge 到 master,使用普通的merge
永远不向master直接commit代码

GitHub Flow 分支模型

只有一个长期分支 master ,而且 master 分支上的代码,永远是可发布状态,

CI(Continuous Integration)集成

netlify

to do

github action

github自带的,貌似比Travis CI好用

ctest 怎么写

自动化生成TOC 目录

可以使用 toc-generator

  1. 在README里配置插入TOC的位置
<!-- START doctoc -->
<!-- END doctoc -->
  1. 配置GitHub Action, 需要在仓库的Settings > Actions > General里的Workflow permissions开启Read and write permissions
name: Generate TOC
on:
push:
    branches:
    - main

jobs:
toc:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - uses: technote-space/toc-generator@v4
        with:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

travis ci

Travis CI 提供的是持续集成服务(Continuous Integration,简称 CI)。它绑定 Github 上面的项目,只要有新的代码,就会自动抓取。然后,提供一个运行环境,执行测试,完成构建,还能部署到服务器。

持续集成的好处在于,每次代码的小幅变更,就能看到运行结果,从而不断累积小的变更,而不是在开发周期结束时,一下子合并一大块代码。

  1. 使用准备
  2. 登录 https://app.travis-ci.com/ ,绑定github,选择监听仓库.
  3. 项目里面有可运行的代码,项目还包含构建或测试脚本
  4. .travis.yml
  5. 在项目根目录下新建 .travis.yml 文件。参考官方文档编写 https://docs.travis-ci.com/user/languages/cpp/
  6. 运行流程
  7. install 阶段:安装依赖
  8. script 阶段:运行脚本
  9. 可选部分
before_install:install 阶段之前执行
before_script:script 阶段之前执行
after_failure:script 阶段失败时执行
after_success:script 阶段成功时执行
before_deploy:deploy 步骤之前执行
after_deploy:deploy 步骤之后执行
after_script:script 阶段之后执行
  1. 运行状态
passed:运行成功,所有步骤的退出码都是0
canceled:用户取消执行
errored:before_install、install、before_script有非零退出码,运行会立即停止
failed :script有非零状态码 ,会继续运行
  1. 可选加密环境变量

git commit 规范

Angular规范

<type>(<scope>): <subject>

type 必须

name description 实例
feat: 新功能(feature)。 打印函数 feat: Add print function for enhanced runtime information
fix/to: 修复bug,可以是QA发现的BUG,也可以是研发自己发现的BUG。
fix: 产生diff并自动修复此问题。适合于一次提交直接修复问题
to: 只产生diff不自动修复此问题。适合于多次提交。最终修复问题提交时使用fix
docs: 文档(documentation)。
style: 格式(不影响代码运行的变动)。
refactor: 重构(即不是新增功能,也不是修改bug的代码变动)。
perf: 优化相关,比如提升性能、体验。
test: 增加测试。
chore: 构建过程或辅助工具的变动。
revert: 回滚到上一个版本。
merge: 代码合并。
sync: 同步主线或分支的Bug。

规范化commit message

格式为:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
  1. 对于Revert: If the commit reverts a previous commit, it should begin with revert:, followed by the header of the reverted commit. In the body it should say: This reverts commit <hash>., where the hash is the SHA of the commit being reverted.
  2. type的类型有:

  3. feat: A new feature

  4. fix: A bug fix
  5. docs: Documentation only changes
  6. style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)空白、格式、缺少分号等
  7. refactor:(重构) A code change that neither fixes a bug nor adds a feature
  8. perf: A code change that improves performance
  9. test: Adding missing or correcting existing tests
  10. chore: (琐事)Changes to the build process or auxiliary tools(辅助工具) and libraries such as documentation generation

  11. scope: commit 改变的位置,如果是多处写*

  12. subject: 简明的描述:
  13. 使用祈使句,现在时态
  14. 不要.结尾
  15. 第一个字母不要大写
  16. body: 包括改变的动机,并将其与以前的行为进行对比。
  17. footer: Breaking Changes或者reference GitHub issues that this commit closes. Breaking Changes should start with the wordBREAKING CHANGE: with a space or two newlines. The rest of the commit message is then used for this.

自动生成Release Notes

规范化commit

插件 vscode插件git-commit-plugin

命令行 husky + commitlint

工具

  1. Standard Version
  2. 实现自动化版本控制,自动创建changelog, 创建 git tags
  3. 安装
npm cache clean --force #npm指令清除npm缓存
# 删除node_module包
npm install -g npm # npm 更新到最新
npm install -g n
n latest # node 更新
   Note: the node command changed location and the old location may be remembered in your current shell.
            old : /usr/bin/node
            new : /usr/local/bin/node
   To reset the command location hash either start a new shell, or execute PATH=$PATH"
PATH=/usr/local/bin/:$PATH
npm install -D standard-version
  1. 编写package.json
"scripts": {
   "release": "standard-version"
}
  1. CHANGELOG.md 记录内容的配置

    1. 创建.versionrc
    {
    "types": [
       {"type": "chore", "section":"Others", "hidden": false},
       {"type": "revert", "section":"Reverts", "hidden": false},
       {"type": "feat", "section": "Features", "hidden": false},
       {"type": "fix", "section": "Bug Fixes", "hidden": false},
       {"type": "improvement", "section": "Feature Improvements", "hidden": false},
       {"type": "docs", "section":"Docs", "hidden": false},
       {"type": "style", "section":"Styling", "hidden": false},
       {"type": "refactor", "section":"Code Refactoring", "hidden": false},
       {"type": "perf", "section":"Performance Improvements", "hidden": false},
       {"type": "test", "section":"Tests", "hidden": false},
       {"type": "build", "section":"Build System", "hidden": false},
       {"type": "ci", "section":"CI", "hidden":false}
    ]
    }
    
  2. 使用Standard Version

// 初次发布版本
npm run release --first-release
npm run release #(自动更新版本号,自动更新 CHANGELOG.md, 自动创建 git tag)
git push --follow-tags origin master
  1. 寄
  2. Commitizen for contributors
  3. Linux下commit规范辅助,用来选择(没vscode的时候用)
  4. 用 git-cz 来提交文件
  5. https://www.jianshu.com/p/acfdd4ca0104
  6. Visual Studio Code Commitizen Support vscode的插件
  7. conventional-changelog/commitlint 阻止不规范的提交

github-release-notes

github-release-notes,以下简称 gren ,是用来一键向 github 发布 release notes 的工具。 https://zhuanlan.zhihu.com/p/99499246

https://blog.csdn.net/weixin_39586683/article/details/110643111

release 语义化版本 semver

版本格式:主版本号.次版本号.修订号,版本号递增规则如下:

主版本号:当你做了不兼容的 API 修改, 次版本号:当你做了向下兼容的功能性新增, 修订号:当你做了向下兼容的问题修正。 先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。

Git auto-release requirements

  1. github Actions / travis-ci
  2. 自动化测试
  3. Commitizen / Visual Studio Code Commitizen Support
  4. 规范commit message
  5. standard-version
  6. 更新 package 版本并打 tag
  7. github-release-notes
  8. 生成 release-log

需要进一步的研究学习

写个github模板

  1. 明确文件结构
  2. src/include/build/Doc/Debug/test/example
  3. 清晰的README
  4. Intro/Install&Run/Features/Bugs/Acknowledge
  5. 图片和标签
    1. https://shields.io/category/build
  6. Release的自动发布
  7. 规范commit
  8. 其他自动化的轮子持续整合 (Continuous Integration, CI)
  9. travis ci
  10. github action
    1. ctest 怎么写?
  11. cmake.yml
  12. .github/workflow
    1. https://github.com/iBug/AWS-Lambda-webhook-py/tree/master/.github/workflows
    2. https://github.com/Kirrito-k423/github-stats
  13. 文档生成
    1. doxygen
    2. Doxygen主要解决说明书问题,可以在我们写代码的时候讲注释转化为说明书,Graphviz主要是用于图形展示
    3. 有项目,文件,函数三部分的书写要求 https://www.cnblogs.com/silencehuan/p/11169084.html
  14. Codecov
    1. 代码覆盖率,执行部分占比。因为未执行部分可能是错的
  15. projects/ bug fixs
  16. 设置为 template repository
  17. 查看 https://app.travis-ci.com/github/Kirrito-k423/githubTemplate

plus

将网站变成带名字的md格式参考文献的插件

Boost 设置

set(Boost_USE_STATIC_LIBS ON)

set(Boost_DEBUG ON)

Boost_INCLUDE_DIR: 含有boost头文件的目录 Boost_LIBRARYDIR: 偏好的含有boost库的库目录

https://stackoverflow.com/questions/3897839/how-to-link-c-program-with-boost-using-cmake

Boost Install

http://c.biancheng.net/view/7772.html cache?

cmake boost install path

https://cloud.tencent.com/developer/ask/107360

设置boost-root 查看安装位置

Travis-CI Install

Travis-CI 依赖软件包每次都要重新安装吗

apt-get install in a GitHub Actions workflow

https://stackoverflow.com/questions/57982945/how-to-apt-get-install-in-a-github-actions-workflow

Actions may have no Boost, where

ctest

Ctest add build/bin to test

Ctest https://www.cnblogs.com/hustcpp/p/12922998.html

https://blog.csdn.net/zcteo/article/details/117527823?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-15.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-15.no_search_link

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

还是ipcc的github组织的太烂了,需要学习一下

参考文献

https://zhuanlan.zhihu.com/p/67620599

http://www.ruanyifeng.com/blog/2017/12/travis_ci_tutorial.html

https://github.com/levy9527/blog/issues/1

Linux Executable file: Structure & Running 2

可执行文件的运行

要运行可执行目标文件 prog,我们可以在 Linux shell 的命令行中输入它的名字: linux> ./prog 因为 prog 不是一个内置的 shell 命令,所以 shell 会认为 prog 是一个可执行目标文件。

进程的启动

  • Linux进程的启动是通过父进程复制一个子进程,子进程通过execve系统调用启动加载器。
  • 加载器(loader)删除子进程已有的虚拟存储段,
  • 通过将虚拟地址空间中的页映射到可执行文件的页大小组块,
  • 并创建一组新的代码、数据、堆、栈段,
  • 同时新的堆和栈被初始化为零。
  • 新的代码和数据段被初始化为可执行文件的内容,
  • 最后将CUP指令寄存器设置成可执行文件入口,启动运行。

执行完上述操作后,其实可执行文件的真正指令和数据都没有别装入内存中。操作系统只是通过可执行文件头部的信息建立起可执行文件和进程虚拟内存之间的映射关系而已。

memory map

除了一些头部信息,在加载过程中没有任何从磁盘到内存的数据复制。直到 CPU 引用一个被映射的虚拟页时才会进行复制,此时,操作系统利用它的页面调度机制自动将页面从磁盘传送到内存。

比如,现在程序的入口地址为 0x08048000 ,刚好是代码段的起始地址。当CPU打算执行这个地址的指令时,发现页面 0x8048000 ~ 0x08049000 (一个页面一般是4K)是个空页面,于是它就认为是个页错误。此时操作系统根据虚拟地址空间与可执行文件间的映射关系找到页面在可执行文件中的偏移,然后在物理内存中分配一个物理页面,并在虚拟地址页面与物理页面间建立映射,最后把EXE文件中页面拷贝到内存的物理页面,进程重新开始执行。该过程如下图所示:

接下来,加载器跳转到程序的入口点,也就是 _start函数的地址。这个函数是在系统目标文件 ctrl.o 中定义的,对所有的 C 程序都是一样的。_start 函数调用系统启动函数 __libc_start_main,该函数定义在 libc.so 中。它初始化执行环境,调用用户层的 main 函数,处理 main 函数的返回值,并且在需要的时候把控制返回给内核。

fork 和 execve 函数的差异

  • fork 函数在新的子进程中运行相同的程序,新的子进程是父进程的一个复制品。
  • execve 函数在当前进程的上下文中加载并运行一个新的程序。
  • 它会覆盖当前进程的地址空间,但并没有创建一个新进程。
  • 新的程序仍然有相同的 PID,并且继承了调用 execve 函数时已打开的所有文件描述符。

程序运行途中修改exe程序

  • 由于操作系统使用页表和虚拟内存机制来实现按需加载。按需加载意味着只有在程序执行到需要访问某个代码段时,才会将该代码段从可执行文件加载到内存中。
  • 那么如果我在程序运行的途中重新编译程序,修改了代码段,那么程序会怎么样呢?
  • Chatgpt:运行中的程序尝试执行新的代码时,会发生未定义的行为,因为操作系统不会自动将新的代码加载到正在运行的进程的内存中。
  • 一个页表4KB,一个程序的代码段可能有如下100KB甚至几十MB,不可能全部加载。
# shaojiemike @ snode6 in ~/github/sniper_PIMProf/PIMProf/gapbs on git:dev o [15:15:29]
$ size /usr/lib/llvm-10/bin/llvm-mca
   text    data     bss     dec     hex filename
 144530    6056    8089  158675   26bd3 /usr/lib/llvm-10/bin/llvm-mca

# shaojiemike @ snode6 in ~/github/sniper_PIMProf/PIMProf/gapbs on git:dev o [15:18:14]
$ l /usr/lib/llvm-10/bin/llvm-mca
-rwxr-xr-x 1 root root 153K Apr 20  2020 /usr/lib/llvm-10/bin/llvm-mca

程序运行途中修改python代码

  • 虽然修改python代码类似修改C代码,按理来说不会影响程序进行。但是python是逐行解释执行的,很难让人不思考会不会影响正在运行中的程序。
  • 答案是不会,原因有二:
  • python代码在运行时,会被编译成字节码,然后再执行字节码。修改python代码后,其对应的字节码会在下一次运行程序时,Python解释器对比文件时间戳时更新。
  • Python解释器在运行时,会将所需的文件提前加载到内存里

GDB调试修改

Memalloc

2

Buddy 内存分配

是一种用于管理计算机内存的算法,旨在有效地分配和释放内存块,以防止碎片化并提高内存的使用效率。这种算法通常用于操作系统中,以管理系统内核和进程的内存分配。

Buddy 内存分配算法的基本思想是将物理内存划分为大小相等的块,每个块大小都是 2 的幂次方。每个块可以分配给一个正在运行的进程或内核。当内存被分配出去后,它可以被分割成更小的块,或者合并成更大的块,以适应不同大小的内存需求。

算法的名称 "Buddy" 来自于分配的块之间的关系,其中一个块被称为 "buddy",它是另一个块的大小相等的邻居。这种关系使得在释放内存时,可以尝试将相邻的空闲块合并成更大的块,从而减少内存碎片。

Buddy 内存分配算法的工作流程大致如下:

  1. 初始时,整个可用内存被视为一个大块,大小是 2 的幂次方。

  2. 当一个进程请求内存分配时,算法会搜索可用的块,找到大小合适的块来满足请求。如果找到的块比所需的稍大,它可以被分割成两个相等大小的 "buddy" 块,其中一个分配给请求的进程。

  3. 当一个进程释放内存时,该块会与其 "buddy" 块合并,形成一个更大的块。然后,这个更大的块可以与其它相邻的块继续合并,直到达到较大的块。

Buddy 内存分配算法在一些操作系统中用于管理内核和进程的物理内存,尤其在嵌入式系统和实时操作系统中,以提高内存使用效率和避免碎片化问题。

ucore(Micro-kernel Operating System for Education)

是一个用于教育目的的微内核操作系统

linux遇到问题

我们可window写程序占满16G内存

但是linux,用了3GB就会seg fault

猜想是不是有单进程内存限制 https://www.imooc.com/wenda/detail/570992

而且malloc alloc的空间在堆区,我们可以明显的发现这个空间是被栈区包住的,有限的。windows是如何解决这个问题的呢? 1. 首先这个包住是虚拟地址,通过页表映射到的物理地址是分开的 2. 根据第一点,可以实现高地址动态向上移动

动态数据区一般就是“堆栈”。“栈 (stack)”和“堆(heap)”是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”,所以每个线程虽然 代码一样,但本地变量的数据都是互不干扰。一个堆栈可以通过“基地址”和“栈顶”地址来描述。全局变量和静态变量分配在静态数据区,本地变量分配在动态数 据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。

当进程初始化时,系统会自动为进程创建一个默认堆,这个堆默认所占内存的大小为1M。堆对象由系统进行管理,它在内存中以链式结构存在。

Linux 单进程内存限制

/etc/security/limits.conf

# shaojiemike @ node5 in ~ [6:35:51]
$ ulimit -a
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8192
-c: core file size (blocks)         0
-m: resident set size (kbytes)      unlimited
-u: processes                       513967
-n: file descriptors                1024
-l: locked-in-memory size (kbytes)  65536
-v: address space (kbytes)          unlimited
-x: file locks                      unlimited
-i: pending signals                 513967
-q: bytes in POSIX msg queues       819200
-e: max nice                        0
-r: max rt priority                 0
-N 15:                              unlimited

ulimit -HSn 4096 # H指定了硬性大小,S指定了软性大小,n表示设定单个进程最大的打开文件句柄数量。硬限制是实际的限制,而软限制,是warnning限制,只会做出warning

lsof
文件描述符

文件句柄数

这些限制一般不会限制内存。

超算登录节点任务限制的实现

GNU malloc()

调用malloc(size_t size)函数分配内存成功,总会分配size字节VM(再次强调不是RAM),并返回一个指向刚才所分配内存区域的开端地址。分配的内存会为进程一直保留着,直到你显示地调用free()释放它(当然,整个进程结束,静态和动态分配的内存都会被系统回收)。

GNU libc库提供了二个内存分配函数,分别是malloc()和calloc()。glibc函数malloc()总是通过brk()或mmap()系统调用来满足内存分配需求。函数malloc(),根据不同大小内存要求来选择brk(),还是mmap(),阈值 MMAP_THRESHOLD=128Kbytes是临界值。小块内存(<=128kbytes),会调用brk(),它将数据段的最高地址往更高处推(堆从底部向上增长)。大块内存,则使用mmap()进行匿名映射(设置标志MAP_ANONYMOUS)来分配内存,与堆无关,在堆之外。

malloc不是直接分配内存的,是第一次访问的时候才分配的?

https://www.zhihu.com/question/20836462

问题

  1. 堆区和栈区是进程唯一的吗?
  2. 是的,而且栈主要是为一个线程配备,小可以保证基本在cache里
  3. 两个操作系统的malloc的是物理内存还是虚拟内存
  4. Linux采用的是copy-on-write机制

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

每次都是6008这里,40000*6008*3/1024/1024=687MB 733448/1024=716MB 问了大师兄,问题竟然是malloc的传入参数错误的类型是int,导致存不下3*40*1024*40*1024。应该用size_t类型。(size_t是跨平台的非负整数安全类型)

参考文献

https://blog.csdn.net/shenzi/article/details/3972437?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.base&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.base

程序(进程)内存空间分布深入理解