我想知道这个陈述背后的逻辑,证据.对于任何x,C表达式-x,~x + 1和〜(x-1)都产生相同的结果.我可以证明这对于具体的例子是正确的.我认为证明这一点的方法与两个补码的属性有关.有任何想法吗?
我不确定会有什么样的东西会被称为(因此笨拙的标题),但我需要这样的东西来处理我正在做的事情.我无法用言语形容它,但我希望这张图能为我解释:

在这个例子中,当任意"索引"(例如5)之后的所有内容都被忽略时,获得"on-bits"数量的最快方法是什么?
我正在寻找相关的性能指标来基准测试和优化我的C / C ++代码。例如,虚拟内存使用率是一个简单但有效的指标,但是我知道有些虚拟内存使用情况更为专业,可以帮助优化特定域:高速缓存命中/未命中,上下文切换等。
我相信这里是一个列出性能指标,衡量指标以及如何衡量指标的好地方,以帮助希望开始优化程序的人员知道从何开始。
我有一个位位置(它永远不会为零),通过使用 tzcnt 计算得出,我想从该位置开始将高位归零。这是 C++ 和反汇编代码(我使用的是 MSVC):
auto position = _tzcnt_u64(xxx);
auto masked =_bzhi_u64(yyy, static_cast<uint32_t>(position));
Run Code Online (Sandbox Code Playgroud)
tzcnt rcx,rdx
mov ecx,ecx
bzhi rax,rbx,rcx
Run Code Online (Sandbox Code Playgroud)
BZHI 接受 unsigned int 作为第二个参数,但仅使用 rcx 中的位 [7..0],因此我认为这个“mov”指令是不必要的。
我用它来稍后计算 popcount,所以我也可以使用类似 <<(64-position) 的东西来代替。
问题是 - 这两个代码具有相同的执行时间,尽管 bzhi 应该比 sub+shlx 执行得更快,所以 mov 可能会产生差异。
有没有办法避免它或者这是编译器的事情?
c++ assembly bit-manipulation compiler-optimization visual-c++
我认为我对延迟和吞吐量之间的差异有一个很好的理解.但是,对于Intel Intrinsics来说,延迟对指令吞吐量的影响并不清楚,特别是在顺序(或几乎顺序)使用多个内部调用时.
例如,让我们考虑一下:
_mm_cmpestrc
Run Code Online (Sandbox Code Playgroud)
它的延迟为11,Haswell处理器的吞吐量为7.如果我在一个循环中运行这个指令,那么在11个循环后我会得到一个连续的每循环输出吗?由于这需要一次运行11条指令,并且因为我的吞吐量为7,所以我是否会用完"执行单元"?
我不确定如何使用延迟和吞吐量,除了得到一条指令相对于不同版本的代码需要多长时间的印象.
我试图编译Zend引擎的这个溢出检测宏:
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
long __tmpvar; \
__asm__( \
"mul %0, %2, %3\n" \
"smulh %1, %2, %3\n" \
"sub %1, %1, %0, asr #63\n" \
: "=X"(__tmpvar), "=X"(usedval) \
: "X"(a), "X"(b)); \
if (usedval) (dval) = (double) (a) * (double) (b); \
else (lval) = __tmpvar; \
} while (0)
Run Code Online (Sandbox Code Playgroud)
并在装配中得到了这个结果:
; InlineAsm Start
mul x8, x8, x9
smulh x9, x8, x9
sub x9, x9, x8, asr #63
; InlineAsm End
Run Code Online (Sandbox Code Playgroud)
编译器仅对宏的输入和输出使用2个寄存器,我认为它必须至少为3,并导致错误的计算结果(例如,-1*-1).有什么建议吗?
assembly ×2
c++ ×2
performance ×2
algorithm ×1
benchmarking ×1
c ×1
clang ×1
cpu ×1
gcc ×1
intrinsics ×1
llvm ×1
optimization ×1
profiling ×1
proof ×1
sse ×1
visual-c++ ×1
x86 ×1