相关疑难解决方法(0)

用64位替换32位循环计数器会引入疯狂的性能偏差

我一直在寻找最快的方法来处理popcount大数据.我遇到了一个很奇怪的效果:改变从循环变量unsigneduint64_t50%在我的电脑上所做的性能下降.

基准

#include <iostream>
#include <chrono>
#include <x86intrin.h>

int main(int argc, char* argv[]) {

    using namespace std;
    if (argc != 2) {
       cerr << "usage: array_size in MB" << endl;
       return -1;
    }

    uint64_t size = atol(argv[1])<<20;
    uint64_t* buffer = new uint64_t[size/8];
    char* charbuffer = reinterpret_cast<char*>(buffer);
    for (unsigned i=0; i<size; ++i)
        charbuffer[i] = rand()%256;

    uint64_t count,duration;
    chrono::time_point<chrono::system_clock> startP,endP;
    {
        startP = chrono::system_clock::now();
        count = 0;
        for( unsigned k = 0; k < …
Run Code Online (Sandbox Code Playgroud)

c++ performance x86 assembly compiler-optimization

1370
推荐指数
9
解决办法
15万
查看次数

如何计算32位整数中的设置位数?

代表数字7的8位看起来像这样:

00000111
Run Code Online (Sandbox Code Playgroud)

设置三位.

什么算法来确定32位整数中的设置位数?

algorithm binary bit-manipulation hammingweight iec10967

838
推荐指数
31
解决办法
52万
查看次数

为什么破坏LZCNT的"输出依赖性"很重要?

在测量某些东西的同时,我测量的吞吐量比我计算的要低得多,我将其缩小到LZCNT指令(它也发生在TZCNT中),如以下基准所示:

  xor ecx, ecx
_benchloop:
  lzcnt eax, edx
  add ecx, 1
  jnz _benchloop
Run Code Online (Sandbox Code Playgroud)

和:

  xor ecx, ecx
_benchloop:
  xor eax, eax  ; this shouldn't help, but it does
  lzcnt eax, edx
  add ecx, 1
  jnz _benchloop
Run Code Online (Sandbox Code Playgroud)

第二个版本要快得多.它不应该.LZCNT没有理由对其输出有输入依赖性.与BSR/BSF不同,xZCNT指令总是覆盖其输出.

我在4770K上运行它,所以LZCNT和TZCNT没有被执行为BSR/BSF.

这里发生了什么?

x86 assembly

22
推荐指数
1
解决办法
1339
查看次数

x86 bsr/bsf如何具有固定的延迟,而不是数据依赖?它不像伪代码那样循环比特吗?

我正在试图分析一些x86二进制代码的"时序通道".我发布了一个问题来理解bsf/bsr操作码.

如此高级,这两个操作码可以被建模为"循环",它计算给定操作数的前导零和尾随零.该x86手册对这些操作码具有良好的形式化,如下所示:

IF SRC = 0
  THEN
    ZF ? 1;
    DEST is undefined;
  ELSE
    ZF ? 0;
    temp ? OperandSize – 1;
    WHILE Bit(SRC, temp) = 0
    DO
      temp ? temp - 1;
    OD;
    DEST ? temp;
FI;
Run Code Online (Sandbox Code Playgroud)

但令我惊讶的是,bsf/bsr指令似乎有固定的cpu周期.根据我在这里找到的一些文档:https://gmplib.org/~tege/x86-timing.pdf,似乎它们总是需要8个CPU周期来完成.

所以这是我的问题:

  1. 我确认这些指令有固定的cpu周期.换句话说,无论给出什么操作数,它们总是花费相同的时间来处理,并且没有"时序通道".我在英特尔的官方文档中找不到相应的规格.

  2. 那么为什么有可能呢?显然这是一个"循环"或某种程度,至少是高级别的.背后的设计决策是什么?CPU流水线更容易?

performance x86 assembly intel cpu-architecture

9
推荐指数
1
解决办法
412
查看次数

x64 支持是否意味着 BMI1 支持?

可以安全地假设 x64 构建可以使用TZCNT而无需通过 cpu 标志检查其支持吗?

assembly x86-64 instruction-set bmi

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