相关疑难解决方法(0)

如何证明C语句-x,~x + 1和〜(x-1)产生相同的结果?

我想知道这个陈述背后的逻辑,证据.对于任何x,C表达式-x,~x + 1和〜(x-1)都产生相同的结果.我可以证明这对于具体的例子是正确的.我认为证明这一点的方法与两个补码的属性有关.有任何想法吗?

c proof twos-complement

4
推荐指数
2
解决办法
996
查看次数

在二进制字中找到1的最有效方法?

我不确定会有什么样的东西会被称为(因此笨拙的标题),但我需要这样的东西来处理我正在做的事情.我无法用言语形容它,但我希望这张图能为我解释:

二进制问题图片的事情

在这个例子中,当任意"索引"(例如5)之后的所有内容都被忽略时,获得"on-bits"数量的最快方法是什么?

c++ algorithm bit-manipulation

4
推荐指数
2
解决办法
304
查看次数

与C / C ++最相关的性能指标

我正在寻找相关的性能指标来基准测试和优化我的C / C ++代码。例如,虚拟内存使用率是一个简单但有效的指标,但是我知道有些虚拟内存使用情况更为专业,可以帮助优化特定域:高速缓存命中/未命中,上下文切换等。

我相信这里是一个列出性能指标,衡量指标以及如何衡量指标的好地方,以帮助希望开始优化程序的人员知道从何开始。

cpu optimization performance benchmarking profiling

4
推荐指数
1
解决办法
87
查看次数

避免 bzhi(y, tzcnt(x)) 中不必要的 mov ecx, ecx 指令

我有一个位位置(它永远不会为零),通过使用 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++

4
推荐指数
1
解决办法
562
查看次数

英特尔内在函数中的延迟与吞吐量

我认为我对延迟和吞吐量之间的差异有一个很好的理解.但是,对于Intel Intrinsics来说,延迟对指令吞吐量的影响并不清楚,特别是在顺序(或几乎顺序)使用多个内部调用时.

例如,让我们考虑一下:

_mm_cmpestrc
Run Code Online (Sandbox Code Playgroud)

它的延迟为11,Haswell处理器的吞吐量为7.如果我在一个循环中运行这个指令,那么在11个循环后我会得到一个连续的每循环输出吗?由于这需要一次运行11条指令,并且因为我的吞吐量为7,所以我是否会用完"执行单元"?

我不确定如何使用延迟和吞吐量,除了得到一条指令相对于不同版本的代码需要多长时间的印象.

performance x86 sse intrinsics micro-optimization

3
推荐指数
1
解决办法
1419
查看次数

clang汇编程序的奇怪行为

我试图编译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 gcc llvm clang

2
推荐指数
1
解决办法
253
查看次数