相关疑难解决方法(0)

平均3个长整数

我有3个非常大的有符号整数.

long x = long.MaxValue;
long y = long.MaxValue - 1;
long z = long.MaxValue - 2;
Run Code Online (Sandbox Code Playgroud)

我想计算他们的截断平均值.预期的平均值是long.MaxValue - 1,即9223372036854775806.

无法将其计算为:

long avg = (x + y + z) / 3; // 3074457345618258600
Run Code Online (Sandbox Code Playgroud)

注意:我阅读了有关2个数字的平均值的所有问题,但我不知道该技术如何应用​​于平均3个数字.

使用它会很容易BigInteger,但我们假设我不能使用它.

BigInteger bx = new BigInteger(x);
BigInteger by = new BigInteger(y);
BigInteger bz = new BigInteger(z);
BigInteger bavg = (bx + by + bz) / 3; // 9223372036854775806
Run Code Online (Sandbox Code Playgroud)

如果我转换为double,那么,当然,我失去了精度:

double dx = x;
double dy = y;
double …
Run Code Online (Sandbox Code Playgroud)

.net c# long-integer

102
推荐指数
7
解决办法
8122
查看次数

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
查看次数

在基准测试时防止编译器优化

我最近遇到了这个辉煌的cpp2015演讲CppCon 2015:Chandler Carruth"调优C++:基准测试,CPU和编译器!哦,我的!"

提到的阻止编译器优化代码的技术之一是使用以下函数.

static void escape(void *p) {
  asm volatile("" : : "g"(p) : "memory");
}

static void clobber() {
  asm volatile("" : : : "memory");
}

void benchmark()
{
  vector<int> v;
  v.reserve(1);
  escape(v.data());
  v.push_back(10);
  clobber()
}
Run Code Online (Sandbox Code Playgroud)

我试图理解这一点.问题如下.

1)越过clobber逃脱的好处是什么?

2)从上面的例子看起来,clobber()可以防止先前的语句(push_back)被优化.如果是这样的话,为什么下面的代码片段不正确?

 void benchmark()
 {
     vector<int> v;
     v.reserve(1);
     v.push_back(10);
     clobber()
 }
Run Code Online (Sandbox Code Playgroud)

如果这不够混乱,那么愚蠢(FB的线程化lib)就会有一个更奇怪的实现

相关片段:

template <class T>
void doNotOptimizeAway(T&& datum) {
  asm volatile("" : "+r" (datum));
}
Run Code Online (Sandbox Code Playgroud)

我的理解是上面的片段通知编译器程序集块将写入数据.但是如果编译器发现没有这个数据的消费者,它仍然可以优化生成数据的实体吗?

我认为这不是常识,任何帮助表示赞赏!

c++ gcc clang performance-testing compiler-optimization

10
推荐指数
2
解决办法
2296
查看次数