mad*_*MDT 6 c++ modular-arithmetic
最近我发现mod('%')运算符非常慢.所以我创建了一个像%b一样工作的函数.但它比mod运算符更快吗?
这是我的功能
int mod(int a, int b)
{
int tmp = a/b;
return a - (b*tmp);
}
Run Code Online (Sandbox Code Playgroud)
mad*_*uri 20
根据Chandler Carruth在CppCon 2015上的基准测试,最快的模运算符(在x86上,与Clang编译时)是:
int fast_mod(const int input, const int ceil) {
// apply the modulo operator only when needed
// (i.e. when the input is greater than the ceiling)
return input >= ceil ? input % ceil : input;
// NB: the assumption here is that the numbers are positive
}
Run Code Online (Sandbox Code Playgroud)
我建议你观看整个演讲,他会详细介绍为什么这种方法比%无条件使用更快.
这可能是编译器和平台相关的.
但我感兴趣的是,在我的系统中,你的基准测试似乎是正确的.然而@ 865719答案的方法最快:
#include <chrono>
#include <iostream>
class Timer
{
using clk = std::chrono::steady_clock;
using microseconds = std::chrono::microseconds;
clk::time_point tsb;
clk::time_point tse;
public:
void clear() { tsb = tse = clk::now(); }
void start() { tsb = clk::now(); }
void stop() { tse = clk::now(); }
friend std::ostream& operator<<(std::ostream& o, const Timer& timer)
{
return o << timer.secs();
}
// return time difference in seconds
double secs() const
{
if(tse <= tsb)
return 0.0;
auto d = std::chrono::duration_cast<microseconds>(tse - tsb);
return d.count() / 1000000.0;
}
};
int mod(int a, int b)
{
int tmp=a/b;
return a-(b*tmp);
}
int fast_mod(const int input, const int ceil) {
// apply the modulo operator only when needed
// (i.e. when the input is greater than the ceiling)
return input > ceil ? input % ceil : input;
// NB: the assumption here is that the numbers are positive
}
int main()
{
auto N = 1000000000U;
unsigned sum = 0;
Timer timer;
for(auto times = 0U; times < 3; ++times)
{
std::cout << " run: " << (times + 1) << '\n';
sum = 0;
timer.start();
for(decltype(N) n = 0; n < N; ++n)
sum += n % (N - n);
timer.stop();
std::cout << " %: " << sum << " " << timer << "s" << '\n';
sum = 0;
timer.start();
for(decltype(N) n = 0; n < N; ++n)
sum += mod(n, N - n);
timer.stop();
std::cout << " mod: " << sum << " " << timer << "s" << '\n';
sum = 0;
timer.start();
for(decltype(N) n = 0; n < N; ++n)
sum += fast_mod(n, N - n);
timer.stop();
std::cout << "fast_mod: " << sum << " " << timer << "s" << '\n';
}
}
Run Code Online (Sandbox Code Playgroud)
构建: GCC 5.1.1(x86_64)
g++ -std=c++14 -march=native -O3 -g0 ...
Run Code Online (Sandbox Code Playgroud)
输出:
run: 1
%: 3081207628 5.49396s
mod: 3081207628 4.30814s
fast_mod: 3581207628 2.51296s
run: 2
%: 3081207628 5.5522s
mod: 3081207628 4.25427s
fast_mod: 3581207628 2.52364s
run: 3
%: 3081207628 5.4947s
mod: 3081207628 4.29646s
fast_mod: 3581207628 2.56916s
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9738 次 |
| 最近记录: |