Skip to content

Instantly share code, notes, and snippets.

@mossheim
Last active April 30, 2018 19:26
Show Gist options
  • Save mossheim/405ddbd01daddc91de3ed0b7d1db0195 to your computer and use it in GitHub Desktop.
Save mossheim/405ddbd01daddc91de3ed0b7d1db0195 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define FP double
using std::cout;
using std::endl;
constexpr size_t num_FPs = 8 * 8192;
FP scaleneg_copysign(FP a, FP b)
{
FP c = std::copysign(1.0, a);
c = (c + 1) * 0.5;
return (a * b * (1.0-c)) + (a * c);
}
FP scaleneg_signbit(FP a, FP b)
{
int c = std::signbit(a);
return (a * b * c) + (a * (1.0-c));
}
FP scaleneg_signbit_float(FP a, FP b)
{
FP c = std::signbit(a);
return (a * b * c) + (a * (1.0-c));
}
FP scaleneg_naive(FP a, FP b)
{
return a < 0 ? a * b : a;
}
// between -5 and 5
FP drand() { return ((FP)rand() / RAND_MAX - 0.5) * 10; }
FP nums[num_FPs];
using scaleneg_t = FP (*)(FP, FP);
void time_func(scaleneg_t scaleneg)
{
clock_t begin = std::clock();
FP accum = 0.;
for (size_t i = 0; i < num_FPs; ++i) {
accum += scaleneg(nums[i], nums[i]);
}
clock_t end = std::clock();
cout << "\tTime: " << ((FP)(end - begin) / CLOCKS_PER_SEC) << " [accum=" << accum << "]\n";
}
int main()
{
// fixed-point floating point
cout << std::fixed;
for (size_t i = 0; i < num_FPs; ++i) {
nums[i] = drand();
}
for (size_t i = 0; i < 3; ++i) {
cout << "Run " << (i+1) << endl;
cout << "scaleneg_signbit:" << endl;
time_func(&scaleneg_signbit);
cout << "scaleneg_naive:" << endl;
time_func(&scaleneg_naive);
cout << "scaleneg_copysign:" << endl;
time_func(&scaleneg_copysign);
cout << "scaleneg_signbit_float:" << endl;
time_func(&scaleneg_signbit_float);
}
return 0;
}
@mossheim
Copy link
Author

mossheim commented Apr 30, 2018

Results:

gcc 7

Run 1
scaleneg_signbit:
	Time: 0.000114 [accum=353518.582899]
scaleneg_naive:
	Time: 0.000283 [accum=353518.582899]
scaleneg_copysign:
	Time: 0.000102 [accum=353518.582899]
scaleneg_signbit_float:
	Time: 0.000117 [accum=353518.582899]
Run 2
scaleneg_signbit:
	Time: 0.000115 [accum=353518.582899]
scaleneg_naive:
	Time: 0.000303 [accum=353518.582899]
scaleneg_copysign:
	Time: 0.000106 [accum=353518.582899]
scaleneg_signbit_float:
	Time: 0.000108 [accum=353518.582899]
Run 3
scaleneg_signbit:
	Time: 0.000126 [accum=353518.582899]
scaleneg_naive:
	Time: 0.000342 [accum=353518.582899]
scaleneg_copysign:
	Time: 0.000104 [accum=353518.582899]
scaleneg_signbit_float:
	Time: 0.000126 [accum=353518.582899]

AppleClang 9.0

Run 1
scaleneg_signbit:
	Time: 0.000332 [accum=353518.582899]
scaleneg_naive:
	Time: 0.000062 [accum=353518.582899]
scaleneg_copysign:
	Time: 0.000114 [accum=353518.582899]
scaleneg_signbit_float:
	Time: 0.000347 [accum=353518.582899]
Run 2
scaleneg_signbit:
	Time: 0.000323 [accum=353518.582899]
scaleneg_naive:
	Time: 0.000059 [accum=353518.582899]
scaleneg_copysign:
	Time: 0.000105 [accum=353518.582899]
scaleneg_signbit_float:
	Time: 0.000347 [accum=353518.582899]
Run 3
scaleneg_signbit:
	Time: 0.000351 [accum=353518.582899]
scaleneg_naive:
	Time: 0.000058 [accum=353518.582899]
scaleneg_copysign:
	Time: 0.000103 [accum=353518.582899]
scaleneg_signbit_float:
	Time: 0.000346 [accum=353518.582899]

VS 2017

num_FPs was increased to 8192 * 8192 because of the lower precision of the default clock.

Run 1
scaleneg_signbit:
        Time: 0.348000 [accum=363539847.782539]
scaleneg_naive:
        Time: 0.490000 [accum=363539847.782539]
scaleneg_copysign:
        Time: 1.200000 [accum=363539847.782539]
scaleneg_signbit_float:
        Time: 0.361000 [accum=363539847.782539]
Run 2
scaleneg_signbit:
        Time: 0.355000 [accum=363539847.782539]
scaleneg_naive:
        Time: 0.531000 [accum=363539847.782539]
scaleneg_copysign:
        Time: 1.186000 [accum=363539847.782539]
scaleneg_signbit_float:
        Time: 0.354000 [accum=363539847.782539]
Run 3
scaleneg_signbit:
        Time: 0.357000 [accum=363539847.782539]
scaleneg_naive:
        Time: 0.484000 [accum=363539847.782539]
scaleneg_copysign:
        Time: 1.197000 [accum=363539847.782539]
scaleneg_signbit_float:
        Time: 0.359000 [accum=363539847.782539]

Best:

  • VS 2017: scaleneg_signbit
  • AppleClang: scaleneg_naive
  • gcc 7: scaleneg_copysign (though scaleneg_signbit is nearly the same)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment