Click here to Skip to main content
16,016,489 members
Articles / Programming Languages / Markdown
Tip/Trick

C++11 std::div() Benchmark

Rate me:
Please Sign up or sign in to vote.
4.56/5 (4 votes)
15 Jan 2019CPOL1 min read 16.4K   56   4   13
C++11 std::div() Benchmark

Update: rand() overhead in benchmark has been removed by filling the array with random values beforehand.

C++11 standard introduces std::div() and its siblings on the premise of some compiler can take advantage of the available machine code that compute quotient and remainder of division together. The C++ reference noted, and (updated) according to Petr Kobalíček, this function was never about performance but rounding direction of negative operands. We thank him for his comment.

Until C++11, the rounding direction of the quotient and the sign of the remainder in the built-in division and remainder operators was implementation-defined if either of the operands was negative, but it was well-defined in std::div.

On many platforms, a single CPU instruction obtains both the quotient and the remainder, and this function may leverage that, although compilers are generally able to merge nearby / and % where suitable.

We'll put std::div() to test in this benchmark.

Compiler Tested

  • GCC 7.4.0 on Cygwin
  • Clang 5.0.1 on Cygwin
  • Visual C++ 15.9 Update

OS: Windows 10 Pro

CPU: Intel i76820HQ

Loops: 10 million

Benchmark Code

C++
stopwatch.start("Division and Modulus");
for (size_t i = 0; i < vec.size(); ++i)
{
    TwoNum& a = vec[i];
    result.quot = a.num / a.divisor;
    result.rem = a.num % a.divisor;
    total_result += result.quot + result.rem; // prevent optimize away
}
stopwatch.stop();

total_result = 0L;
stopwatch.start("Custom div function");
for (size_t i = 0; i < vec.size(); ++i)
{
    TwoNum& a = vec[i];
    result = my_div(a.num, a.divisor);
    total_result += result.quot + result.rem; // prevent optimize away
}
stopwatch.stop();

total_result = 0L;
stopwatch.start("std::div function");
for (size_t i = 0; i < vec.size(); ++i)
{
    TwoNum& a = vec[i];
    result = std::div(a.num, a.divisor);
    total_result += result.quot + result.rem; // prevent optimize away
}
stopwatch.stop();

Custom my_div() function is defined as below:

C++
inline std::div_t my_div(int number, int divisior)
{
    return std::div_t{ (number / divisior), (number % divisior) };
}

Unoptimized Benchmark

GCC Unoptimized
Division and Modulus timing:108ms
Custom div function timing:150ms
std::div function timing:104ms

Clang Unoptimized
Division and Modulus timing:104ms
Custom div function timing:184ms
std::div function timing:102ms

VC++ Unoptimized
Division and Modulus timing:411ms
Custom div function timing:465ms
std::div function timing:427ms

On unoptimized GCC and Clang binary, std::div() is faster than my_div() and slightly faster than the individual division and modulus. For VC++, individual division and modulus is faster probably due to no overhead of function call.

Optimized Benchmark

GCC Optimized(O3)
Division and Modulus timing:30ms
Custom div function timing:34ms
std::div function timing:56ms

Clang Optimized(O3)
Division and Modulus timing:31ms
Custom div function timing:32ms
std::div function timing:54ms

VC++ Optimized(Ox)(Ot)
Division and Modulus timing:32ms
Custom div function timing:41ms
std::div function timing:50ms

On optimized binary, it is a shame that std::div() is consistently slower. In conclusion, today's compiler already does a very good job of computing division and modulus together without resorting to std::div() but it still has the performance lead when it comes to unoptimized build.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Singapore Singapore
Shao Voon is from Singapore. His interest lies primarily in computer graphics, software optimization, concurrency, security, and Agile methodologies.

In recent years, he shifted focus to software safety research. His hobby is writing a free C++ DirectX photo slideshow application which can be viewed here.

Comments and Discussions

 
Questionquotient and modulus together Pin
SeattleC++21-Jan-19 9:37
SeattleC++21-Jan-19 9:37 
Suggestionhints to make the benchmark better Pin
vickoza16-Jan-19 10:26
vickoza16-Jan-19 10:26 
AnswerRe: hints to make the benchmark better Pin
Shao Voon Wong16-Jan-19 15:45
mvaShao Voon Wong16-Jan-19 15:45 
SuggestionDifferences in rand() implementation should be affecting too much Pin
Armando A Bouza15-Jan-19 8:59
Armando A Bouza15-Jan-19 8:59 
Dear Shao, I am afraid that the differences in rand() implementation between compilers could be hiding the impact of using sdt:div in the different compilers.
I made a similar experiment with the Intel C++/C compiler and also concluded that using div provided no improvement over "/" plus " %". Modern optimizing compiler are too smart for loosing this basic optimization opportunity.

The execution time you got with MS-VS is really strange, I compared several times VS, Intel, Watcom and GCC, with very different codes, and never get so poor results with VC!
- All the compiler were set to generate 32bits or all were set to 64 bits?
- All of them had the same target CPU? (SSE2 or SSE3 or AVX or AVX2, etc)?
AnswerRe: Differences in rand() implementation should be affecting too much Pin
Shao Voon Wong15-Jan-19 15:56
mvaShao Voon Wong15-Jan-19 15:56 
GeneralRe: Differences in rand() implementation should be affecting too much Pin
Armando A Bouza15-Jan-19 22:57
Armando A Bouza15-Jan-19 22:57 
Questionwhy is vc++ so slow? Pin
Satervalley14-Jan-19 16:40
Satervalley14-Jan-19 16:40 
AnswerRe: why is vc++ so slow? Pin
Member 1052334715-Jan-19 5:38
Member 1052334715-Jan-19 5:38 
GeneralRe: why is vc++ so slow? Pin
Michael Waters15-Jan-19 7:12
Michael Waters15-Jan-19 7:12 
AnswerRe: why is vc++ so slow? Pin
Shao Voon Wong15-Jan-19 15:20
mvaShao Voon Wong15-Jan-19 15:20 
GeneralRe: why is vc++ so slow? Pin
degski15-Jan-19 19:21
degski15-Jan-19 19:21 
GeneralRe: why is vc++ so slow? Pin
Shao Voon Wong16-Jan-19 13:51
mvaShao Voon Wong16-Jan-19 13:51 
GeneralRe: why is vc++ so slow? Pin
degski16-Jan-19 17:56
degski16-Jan-19 17:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.