gpt4 book ai didi

c++ - 为什么 A/ 在 A 无符号与有符号时更快?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:42:01 24 4
gpt4 key购买 nike

<分区>

我一直在阅读 Optimizing C++ wikibook .在faster operations chapter其中一个建议如下:

Integer division by a constant

When you divide an integer (that is known to be positive or zero) by a constant, convert the integer to unsigned.

If s is a signed integer, u is an unsigned integer, and C is a constant integer expression (positive or negative), the operation s / C is slower than u / C, and s % C is slower than u % C. This is most significant when C is a power of two, but in all cases, the sign must be taken into account during division.

The conversion from signed to unsigned, however, is free of charge, as it is only a reinterpretation of the same bits. Therefore, if s is a signed integer that you know to be positive or zero, you can speed up its division using the following (equivalent) expressions: (unsigned)s / C and (unsigned)s % C.

我用 gcc 测试了这个语句,u/C 表达式似乎始终比 s/c 表现得更好

下面还提供了下面的例子:

#include <iostream>
#include <chrono>
#include <cstdlib>
#include <vector>
#include <numeric>

using namespace std;

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

constexpr int vsize = 1e6;
std::vector<int> x(vsize);
std::iota(std::begin(x), std::end(x), 0); //0 is the starting number

constexpr int a = 5;

auto start_signed = std::chrono::system_clock::now();
int sum_signed = 0;
for ([[gnu::unused]] auto i : x)
{
// signed is by default
int v = rand() % 30 + 1985; // v in the range 1985-2014

sum_signed += v / a;
}
auto end_signed = std::chrono::system_clock::now();

auto start_unsigned = std::chrono::system_clock::now();
int sum_unsigned = 0;
for ([[gnu::unused]] auto i : x)
{
int v = rand() % 30 + 1985; // v in the range 1985-2014
sum_unsigned += static_cast<unsigned int>(v) / a;
}
auto end_unsigned = std::chrono::system_clock::now();

// signed
std::chrono::duration<double> diff_signed = end_signed - start_signed;
std::cout << "sum_signed: " << sum_signed << std::endl;
std::cout << "Time it took SIGNED: " << diff_signed.count() * 1000 << "ms" << std::endl;

// unsigned
std::chrono::duration<double> diff_unsigned = end_unsigned - start_unsigned;
std::cout << "sum_unsigned: " << sum_unsigned << std::endl;
std::cout << "Time it took UNSIGNED: " << diff_unsigned.count() * 1000 << "ms" << std::endl;

return 0;
}

您可以在此处编译并运行示例:http://cpp.sh/8kie3

为什么会这样?

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com