环境:
我没有写很多汇编程序代码,当我这么做时,它要么足够短,要么足够简单,以至于我不必担心压缩它的最大数量.我的更复杂的代码通常用C编写,我让编译器的优化器担心延迟,代码对齐等.
但是在我目前的项目中,MSVC的优化器在关键路径中的代码上做得非常糟糕.所以...
我还没有找到一个好的工具,可以对x64汇编代码进行静态或运行时分析,以便消除停顿,改善延迟等等.我所拥有的只是VS分析器,它告诉我(大致)哪些指令花了最多的时间.墙上的时钟告诉我最近的变化是否使事情变得更好或更糟.
作为替代方案,我一直在通过Agner的文档进行操作,希望能从我的代码中挤出一些更多的信息.问题是,在你理解了所有这些工作之前,很难理解他的任何工作.但它的一部分是有意义的,我正在尝试应用我学到的东西.
记住这一点,这里是我最内层循环的核心(不足为奇)是VS剖析器说我花费的时间:
nottop:
vpminub ymm2, ymm2, ymm3 ; reset out of range values
vpsubb ymm2, ymm2, ymm0 ; take a step
top:
vptest ymm2, ymm1 ; check for out of range values
jnz nottop
; Outer loop that does some math, does a "vpsubb ymm2, ymm2, ymm0",
; and eventually jumps back to top
Run Code Online (Sandbox Code Playgroud)
是的,这几乎是一个依赖链的教科书示例:这个紧密的小循环中的每个指令都取决于前一个操作的结果.这意味着没有并行性,这意味着我没有充分利用处理器.
受Agner的"优化汇编程序"文档的启发,我想出了一种方法(希望)允许我一次做2个操作,所以我可以有一个管道更新ymm2和另一个更新(比如说)ymm8.
虽然这是一个非平凡的变化,所以在我开始撕掉所有东西之前,我想知道它是否可能有所帮助.看看Agner的kaby lake(我的目标)的"指令表",我看到:
uops
each
port Latency
pminub …
Run Code Online (Sandbox Code Playgroud) 根据扩展汇编程序的gcc文档:
当操作数的约束允许寄存器时,您应该只使用读写操作数.
这似乎是非常明确的:你不能使用+ m作为输出.
但是,我已经看过很多次了.事实上,Linus Torvalds有记录说
gcc文档是次要的.他们没有更新,他们不正确,他们没有反映现实,他们并不重要.对于像这样的事情,唯一正确的用法是"+ m"
如果编译器最终搞砸了我的代码,我不想使用+ m.甚至检查输出asm以确定它是否正常工作并不意味着明天当我改变一些看似无关的东西时它仍然会起作用.或者当我获得gcc的下一次更新时它仍然可以工作.
如果文档是正确的,我不能依赖于这种正常工作,我想知道,所以我可以寻求其他选择(其中大多数是令人不快的痛苦).如果文档错误,请告诉我如何纠正它们.
$ clang --version
clang version 5.0.0 (tags/RELEASE_500/final)
Run Code Online (Sandbox Code Playgroud)
。
CC ../../py/nlrthumb.c
../../py/nlrthumb.c:79:5: error: non-ASM statement in naked function is not supported
return 0; // needed to silence compiler warning
Run Code Online (Sandbox Code Playgroud)
为什么 Clang 不支持non-ASM statement in naked function
?
这在gcc
.
邮件列表将其解释为
裸函数没有序言或尾声,因此对内联汇编以外的任何内容进行代码生成都可能完全失败。
那么怎么gcc
办呢?
我试图在我的项目中使用第三方.net 4.6 dll.这个dll的大小是40mb,一切正常.
然而,加载我的DLL的应用程序中有一个错误,当加载的dll大于10mb时崩溃.这是固定的,但暂时还没准备好.
为了不拖延我的项目是否可以将.NET程序集拆分为更小的块,但仍然有引用程序集正确加载所有内容?