Esper 发布的文章

最近看到rpcs3中用到了asmjit,就去其官方项目上看了一下,根据描述是个即时生成目标平台汇编代码的库,但是看了一下样例之后发现有些东西还是没法完全理解。其中之一就是ret指令。在样例代码中是这么写的:

  ...
  x86::Assembler a(&code);
  a.mov(x86::eax, 2);
  a.add(x86::eax, -3);
  a.ret();
  ...

然后就想,既然Assembler模拟的是汇编指令,那么ret指令返回EAX的值会不会是某种约定呢? 然后打算查阅Intel的汇编指令手册,官方名叫Intel® 64 and IA-32 Architectures Software Developer’s Manual,里面有对指令的详细介绍。看到ret指令对应的伪代码有整整几页,有点慌啊。。 其中有这么几句:

IF top 4 bytes of stack not within stack limits
    THEN #SS(0); FI;
EIP ← Pop();

当时就对这个#SS(0);有点迷惑。然后在谷歌上查到了相似的使用方法,但是仍然没看到正式的定义。但是在一个网站上可能看到了类似的定义(http://www.scs.stanford.edu/05au-cs240c/lab/i386/RET.htm,惊了,是斯坦福):

Protected Mode Exceptions #GP, #NP, or #SS, as described under "Operation" above; #PF(fault-code) for a page fault

然后便开始猜测#<abbr>(<val>)的用法为带返回码的异常抛出:其中PF对应page fault的话,根据搜索,SS对应的为stack smashing,即栈溢出;GP对应general peotection,该机制旨在确保程序访问有效的地址区域;但是NP这个not present就有点搞不懂了。。似乎是指什么不存在?

虽然还是有对不上的。。但是大部分意义都是可以对上的,因而认为猜测正确。

总而言之,这个格式的意义是明白了:Intel使用的伪代码中的异常抛出语句。

LLVM连同组件一起编译

对LLVM有初步了解的话,会发现LLVM可以被描述为编译器的“中后端”。也就是说,LLVM本身不是一个完整的编译器,需要与编译器前端等组件配合使用才能完成完整的编译过程。作为可选组件形式与LLVM一同发布的配件就有配置的讲究了。 根据CMakeList文件对组件的配置,加上网上其他人对于编译过程的总结,对组件及其位置罗列如下:

文件名 对应组件 对应位置
llvm-.src.tar.gz LLVM本体 ./
cfe-.src.tar.gz Clang ./tools/clang
compiler-rt-.src.tar.gz Compiler-RT ./projects/compiler-rt
libcxx-.src.tar.gz libcxx ./projects/libcxx
libcxxabi-.src.tar.gz libcxxabi ./projects/libcxxabi
libunwind-.src.tar.gz libunwind ./projects/libunwind
lld-.src.tar.gz LLVM连接器 ./tools/lld
lldb-.src.tar.gz LLVM调试器 ./tools/lldb
openmp-.src.tar.gz OpenMP支持 ./projects/openmp
polly-.src.tar.gz (暂时不懂) ./tools/polly
clang-tools-extra-.src.tar.gz Clang附加工具 ./tools/clang/tools/extra
test-suite-.src.tar.gz 测试程序(相当大) ./projects/test-suite

编译时遇到错误:r7 cannot be used in asm here

https://tls.mbed.org/kb/development/arm-thumb-error-r7-cannot-be-used-in-asm-here

根据上述网站叙述,该问题在于gcc对于arm处理器中寄存器的使用方式与arm自身对编译过程的优化中产生了冲突。arm优化的函数在汇编中显式地使用了编号为r7的寄存器,而在不经优化的情况下,r7被gcc用作帧指针寄存器,不允许被显示地用作其他用途,从而报错。

在解决这个问题时,发现另一个问题:理论情况来说,发布的稳定版的软件源码在编译时会默认设置为发布版本Release,在该模式下,编译器将会对目标软件进行大幅优化以加快运行速度(比如常见的开启-O2-O3选项),删除不必要的调试信息从而缩小软件大小。而LLVM却将其默认设置为了调试版本Debug,在该模式下,将保留较多的源代码信息,能够在出错时较好地帮助开发人员进行调试,也会相比发布版本有着更加接近原代码的二进制逻辑过程,而这也正是上面在直接编译LLVM时遇到错误的原因。

因而解决方法十分清晰了:将CMake中决定编译版本的参数设置为Release即可。

cd /path/to/llvm/src
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release

然后再加上其他需要的参数配置完以后,使用make进行编译即可。

若是只想解决该问题并编译调试版本的话,在编译器参数中加上-fomit-frame-pointer选项即可。

台式机,E3 1245 v2,风扇是玄冰300,之前装电脑的时候不懂事,把涂好了硅脂的新风扇按上cpu后,又拿下来看一下压匀没再装上去。(错误操作请勿模仿:这样会在cpu与风扇接触面之间产生气泡,降低导热效率)用了一年,拆下来之前试了一下,开个rpcs3游戏,(咳咳,rpcs3性能测试专用软件——冷门星mk2(大雾)),六十五六度的样子。

然后本来打算给用了两年的笔记本换个7921,结果。。拆的时候散热螺丝拆坏了,花钱修好顺便上了原装硅脂。然后就想起了如上所述的神奇操作,感觉还是换一下比较好。然后两个重点:

  1. 玄冰300的正确拆卸方式 玄冰300的固定原理是用卡扣将风扇固定在(固定在主板上的)底座上。将风扇上与卡扣相连的金属环向下压,将卡扣较为自然地移出即可。

  2. 7921的正确涂法 网传众多涂法,包括一字、十字、五点、九点,甚至涂匀。台式机上可以直接涂一字,与散热铜管方向垂直即可。(经少量硅脂测试,在涂成圆点的情况下会按照铜管方向扩散得更远)从左涂到右,两边可以留个2-3mm左右的间距,然后直接平压安装风扇即可。这个时候要保证cpu和风扇紧贴,不然进气泡就没什么意义了= =涂完之后从四周侧边观察,有极少量的硅脂溢出,猜测恰好覆盖完全。 笔记本的话可以考虑用刮板在核心上涂好再装散热。但是根据网友反映,这橡皮泥黏刮板比黏核心严重多了。。因而有网友提出,可以按照散热上的金属标记槽(往往是方形)涂好硅脂,然后再与核心贴合。

然后再开冷门星mk2,温度都上不了60度了,快乐

https://devtalk.nvidia.com/default/topic/1049681/nsight-visual-studio-edition/nvidia-nsight-visual-studio-edition-2019-1-with-cuda-9-2/

  1. C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\extras\visual_studio_integration\MSBuildExtensions下的文件复制到C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Microsoft\VC\v160\BuildCustomizations

  2. 编辑C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\include\crt\host_config.h的133-135行,强行添加对新版本VC++的支持。把133行的1913改成1921,要是不怕出事可以直接注释掉整个if。我的个人修改方法:在修改133行的同时,139行插入
#elif _MSC_VER == 1921

#pragma message("support for Microsoft Visual Studio 2019 is unofficial!")

用于验证修改是否有效。

有一点要注意的是,CUDA若是安装在默认的X:\Program Files目录下的话,修改其中的文件通常需要管理员权限。而我使用的gedit会很神奇地在没有权限的时候(即以普通用户权限保存文件),不知道自动在哪创建一个同名副本保存,并且还会每次贴心地读取副本。。。我一直以为是哪里缓存的问题,直到重启电脑发现文件变回原样才想起来。。。所以说在权限问题上尽量要清晰,不要偷懒或者马虎。

由于在配置直接使用网线进行的远程桌面连接时,操作太急,把弹出的提示框直接关掉了。 然后发现在网络管理中心,在同一张网卡、同一个网络下,多出了一个“未识别网络”。这玩意不但碍眼,还导致网络访问速度(甚至成功率)有一定的下降。

在经过长时间的网络搜寻之后,在这个帖子里获得了灵感。在该文中提到,提问者是由于在一张网卡上配置了两个网关,导致Windows会对经由每一个网关的网络连通性进行检测,若是数据包发错了路由,就会无法正常与服务器通讯,出现网络错误。

回想之前的操作过程中,由于急着修改IP地址,忘记网关没有修改了,然后Windows自动为其配置成了多网关模式,而这就导致了上述情况的发生,回去查看连接属性,果然有两个网关。先点选手动分配IP地址,然后删掉那个多余的网关,再重新切换回自动分配模式即可。