相关疑难解决方法(0)

浮点除法与浮点乘法

通过编码是否有任何(非微优化)性能增益

float f1 = 200f / 2
Run Code Online (Sandbox Code Playgroud)

在比较中

float f2 = 200f * 0.5
Run Code Online (Sandbox Code Playgroud)

几年前我的一位教授告诉我,浮点除法比浮点乘法慢,但没有详细说明原因.

这句话适用于现代PC架构吗?

UPDATE1

关于评论,请同时考虑这个案例:

float f1;
float f2 = 2
float f3 = 3;
for( i =0 ; i < 1e8; i++)
{
  f1 = (i * f2 + i / f3) * 0.5; //or divide by 2.0f, respectively
}
Run Code Online (Sandbox Code Playgroud)

更新2 从评论中引用:

[我想]知道什么是算法/架构要求导致>除法在硬件上比复制要复杂得多

c++ floating-point micro-optimization

67
推荐指数
5
解决办法
5万
查看次数

x86的MOV真的可以"免费"吗?为什么我不能重现这个呢?

我一直看到人们声称MOV指令可以在x86中免费,因为寄存器重命名.

对于我的生活,我无法在一个测试用例中验证这一点.每个测试用例我尝试揭穿它.

例如,这是我用Visual C++编译的代码:

#include <limits.h>
#include <stdio.h>
#include <time.h>

int main(void)
{
    unsigned int k, l, j;
    clock_t tstart = clock();
    for (k = 0, j = 0, l = 0; j < UINT_MAX; ++j)
    {
        ++k;
        k = j;     // <-- comment out this line to remove the MOV instruction
        l += j;
    }
    fprintf(stderr, "%d ms\n", (int)((clock() - tstart) * 1000 / CLOCKS_PER_SEC));
    fflush(stderr);
    return (int)(k + j + l);
}
Run Code Online (Sandbox Code Playgroud)

这为循环生成以下汇编代码(随意生成这个你想要的;你显然不需要Visual C++):

LOOP:
    add edi,esi
    mov …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly cpu-registers micro-optimization

23
推荐指数
2
解决办法
2113
查看次数

为什么 for 循环体中的一个基本算术运算执行得比两个算术运算慢?

当我尝试测量算术运算的执行时间时,我遇到了非常奇怪的行为。包含for循环体中具有一个算术运算的循环的代码块总是比相同的代码块执行得慢,但在for循环体中具有两个算术运算。这是我最终测试的代码:

#include <iostream>
#include <chrono>

#define NUM_ITERATIONS 100000000

int main()
{
    // Block 1: one operation in loop body
    {
        int64_t x = 0, y = 0;
        auto start = std::chrono::high_resolution_clock::now();

        for (long i = 0; i < NUM_ITERATIONS; i++) {x+=31;}

        auto end = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double> diff = end-start;
        std::cout << diff.count() << " seconds. x,y = " << x << "," << y << std::endl;
    }

    // Block 2: two operations in loop …
Run Code Online (Sandbox Code Playgroud)

c++ performance assembly cpu-architecture google-benchmark

15
推荐指数
3
解决办法
863
查看次数

在Windows上,试用版代码的运行速度比32位快32倍,而在Linux上则高于64位

我有一段代码,在Windows上运行速度比在linux上快2倍.这是我测量的时间:

g++ -Ofast -march=native -m64
    29.1123
g++ -Ofast -march=native
    29.0497
clang++ -Ofast -march=native
    28.9192
visual studio 2013 Debug 32b
    13.8802
visual studio 2013 Release 32b
    12.5569
Run Code Online (Sandbox Code Playgroud)

这似乎是一个太大的差异.

这是代码:

#include <iostream>
#include <map>
#include <chrono>
static std::size_t Count = 1000;

static std::size_t MaxNum = 50000000;

bool IsPrime(std::size_t num)
{
    for (std::size_t i = 2; i < num; i++)
    {
        if (num % i == 0)
            return false;
    }
    return true;
}

int main()
{
    auto start = std::chrono::steady_clock::now();
    std::map<std::size_t, bool> value; …
Run Code Online (Sandbox Code Playgroud)

c++ performance benchmarking x86 32bit-64bit

12
推荐指数
2
解决办法
931
查看次数

Clang 中的 256 位算术(扩展整数)

我正处于一个项目的设计阶段,该项目需要执行大量简单的 256 位整数运算(仅加、子、多、分),并且需要针对这四个操作进行合理优化的东西。

我已经熟悉 GMP、NTL 和大多数其他重量级 bignum 实现。然而,这些实现的开销促使我做我自己的低级实现——我真的不想这样做;众所周知,这东西很难做对。

在我的研究中,我注意到 Clang 中新的扩展整数类型 - 我是 gcc 用户 - 我想知道是否有人对现实生活中的扩展整数有任何经验,愤怒的实现?它们是否针对“明显的”位大小(256、512 等)进行了优化?

我在 linux 下的 x-64 上使用 C 语言(目前是 Ubuntu,但如果需要,可以向其他发行版开放)。我主要使用 gcc 进行生产工作。

编辑添加:@phuclv 确定了以前的答案C++ 128/256-bit fixed size integer types。(感谢@phuclv。)这个q/a 侧重于c++ 支持;我希望确定是否有人对新的 Clang 类型有任何特定的经验。

c x86-64 clang bigint extint

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

GCC的sqrt()如何在编译后工作?使用哪种root方法?牛顿迭代?

sqrt()关于GCC的math.h 标准的好奇心.我sqrt()使用Newton-Raphson 编写了自己的代码!

c math assembly function sqrt

5
推荐指数
2
解决办法
239
查看次数

在某些情况下,在x86-64 Intel / AMD CPU上,128bit / 64bit硬件无符号除法能否比64bit / 32bit除法更快?

可以通过硬件128bit / 64bit除法指令执行缩放的64bit / 32bit除法,例如:

; Entry arguments: Dividend in EAX, Divisor in EBX
shl rax, 32  ;Scale up the Dividend by 2^32
xor rdx,rdx
and rbx, 0xFFFFFFFF  ;Clear any garbage that might have been in the upper half of RBX
div rbx  ; RAX = RDX:RAX / RBX
Run Code Online (Sandbox Code Playgroud)

...在某些特殊情况下,比硬件64位/ 32位除法指令执行的缩放64位/ 32位除法更快,例如:

; Entry arguments: Dividend in EAX, Divisor in EBX
mov edx,eax  ;Scale up the Dividend by 2^32
xor eax,eax
div ebx  ; EAX = EDX:EAX / EBX
Run Code Online (Sandbox Code Playgroud)

“某些特殊情况”是指异常的红利和除数。我只想比较 …

performance x86 assembly x86-64 integer-division

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

绩效评估的惯用方法?

我正在评估我的项目的网络+渲染工作负载。

程序连续运行一个主循环:

while (true) {
   doSomething()
   drawSomething()
   doSomething2()
   sendSomething()
}
Run Code Online (Sandbox Code Playgroud)

主循环每秒运行 60 多次。

我想查看性能故障,每个程序需要多少时间。

我担心的是,如果我打印每个程序的每个入口和出口的时间间隔,

这会导致巨大的性能开销。

我很好奇什么是衡量性能的惯用方法。

日志打印是否足够好?

benchmarking microbenchmark

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

C程序中系数的两个uint64_t数乘除法GCC编译错误

众所周知,定点算术等同于具有某些约束的整数算术。这样我就抓住了这个问题。让我们来看看:

#include <stdio.h>
#include <stdint.h>

#define USE_C_FUNC 1

#if USE_C_FUNC != 0
uint64_t fixmd(uint64_t a, uint64_t b)
{
    uint64_t c = a * b / 10000000000LL;
    return c;
}
#else
uint64_t fixmd(uint64_t a, uint64_t b)
{
    uint64_t c;

    asm (
    "mov %1, %%rax\n"
    "mul %2\n"
    "mov $10000000000, %%r8\n"
    "div %%r8\n"
    "mov %%rax, %0\n"
    : "=r" (c) 
    : "r" (a), "r" (b)
    : "rax", "rdx", "r8"
    );
    return c;
}
#endif

void main(void)
{
    uint64_t x = 12589254118LL;
    uint64_t y = …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc compilation

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