fix exp/log performance-related issues on Linux/x86_64
parent
56cf1882fd
commit
999540bfcf
|
@ -51,9 +51,9 @@ public:
|
|||
m_points.clear();
|
||||
m_points.reserve(m_size.x*m_size.y);
|
||||
m_size = size; m_pos = PointType(0);
|
||||
const Float invLog2 = (Float) 1 / std::log((Float) 2);
|
||||
const Float invLog2 = (Float) 1 / std::fastlog((Float) 2);
|
||||
generate(
|
||||
(int) std::ceil(invLog2 * std::log((Float) std::max(m_size.x, m_size.y))),
|
||||
(int) std::ceil(invLog2 * std::fastlog((Float) std::max(m_size.x, m_size.y))),
|
||||
ENorth, EEast, ESouth, EWest);
|
||||
}
|
||||
|
||||
|
|
|
@ -512,7 +512,7 @@ public:
|
|||
inline Spectrum exp() const {
|
||||
Spectrum value;
|
||||
for (int i=0; i<SPECTRUM_SAMPLES; i++)
|
||||
value.s[i] = std::exp(s[i]);
|
||||
value.s[i] = std::fastexp(s[i]);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,49 @@ using std::compose1;
|
|||
#endif
|
||||
|
||||
namespace std {
|
||||
#if defined(__LINUX__) && defined(__x86_64__)
|
||||
/*
|
||||
The Linux/x86_64 single precision implementations of 'exp'
|
||||
and 'log' suffer from a serious performance regression.
|
||||
It is about 5x faster to use the double-precision versions
|
||||
with the extra overhead of the involved FP conversion.
|
||||
|
||||
Until this is fixed, the following aliases make sure that
|
||||
the fastest implementation is used in every case.
|
||||
*/
|
||||
inline float fastexp(float value) {
|
||||
return (float) ::exp((double) value);
|
||||
}
|
||||
|
||||
inline double fastexp(double value) {
|
||||
return ::exp(value);
|
||||
}
|
||||
|
||||
inline float fastlog(float value) {
|
||||
return (float) ::log((double) value);
|
||||
}
|
||||
|
||||
inline double fastlog(double value) {
|
||||
return ::log(value);
|
||||
}
|
||||
#else
|
||||
inline float fastexp(float value) {
|
||||
return ::expf(value);
|
||||
}
|
||||
|
||||
inline double fastexp(double value) {
|
||||
return ::exp(value);
|
||||
}
|
||||
|
||||
inline float fastlog(float value) {
|
||||
return ::logf(value);
|
||||
}
|
||||
|
||||
inline double fastlog(double value) {
|
||||
return ::log(value);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_GNU_SOURCE)
|
||||
inline void sincos(float theta, float *sin, float *cos) {
|
||||
::sincosf(theta, sin, cos);
|
||||
|
@ -102,17 +145,18 @@ namespace std {
|
|||
inline void sincos(double theta, double *sin, double *cos) {
|
||||
::sincos(theta, sin, cos);
|
||||
}
|
||||
|
||||
#else
|
||||
inline void sincos(float theta, float *_sin, float *_cos) {
|
||||
float sinValue = sinf(theta);
|
||||
*_sin = sinValue;
|
||||
*_cos = sqrtf(1.0f-sinValue*sinValue);
|
||||
*_cos = sqrtf(std::max(0.0f, 1.0f-sinValue*sinValue));
|
||||
}
|
||||
|
||||
inline void sincos(double theta, double *_sin, double *_cos) {
|
||||
double sinValue = sin(theta);
|
||||
*_sin = sinValue;
|
||||
*_cos = sqrt(1.0-sinValue*sinValue);
|
||||
*_cos = sqrt(std::max(0.0, 1.0-sinValue*sinValue));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -258,7 +258,7 @@ public:
|
|||
|
||||
ref<Random> random = new Random(seed);
|
||||
Float xi = random->nextFloat();
|
||||
intensityVariation = std::min(-std::log(xi), (Float) 10.0f);
|
||||
intensityVariation = std::min(-std::fastlog(xi), (Float) 10.0f);
|
||||
}
|
||||
|
||||
result = yarn.ks * (intensityVariation * m_ksMultiplier * integrand);
|
||||
|
@ -545,7 +545,7 @@ public:
|
|||
}
|
||||
|
||||
inline Float atanh(Float arg) const {
|
||||
return std::log((1.0f + arg) / (1.0f - arg)) / 2.0f;
|
||||
return std::fastlog((1.0f + arg) / (1.0f - arg)) / 2.0f;
|
||||
}
|
||||
|
||||
// von Mises Distribution
|
||||
|
@ -560,12 +560,12 @@ public:
|
|||
+ t*(0.2659732f + t*(0.0360768f + t*0.0045813f)))));
|
||||
} else {
|
||||
Float t = 3.75f / absB;
|
||||
I0 = std::exp(absB) / std::sqrt(absB) * (0.39894228f + t*(0.01328592f
|
||||
I0 = std::fastexp(absB) / std::sqrt(absB) * (0.39894228f + t*(0.01328592f
|
||||
+ t*(0.00225319f + t*(-0.00157565f + t*(0.00916281f + t*(-0.02057706f
|
||||
+ t*(0.02635537f + t*(-0.01647633f + t*0.00392377f))))))));
|
||||
}
|
||||
|
||||
return std::exp(b * cos_x) / (2 * M_PI * I0);
|
||||
return std::fastexp(b * cos_x) / (2 * M_PI * I0);
|
||||
}
|
||||
|
||||
/// Attenuation term
|
||||
|
|
|
@ -117,7 +117,7 @@ public:
|
|||
case EBeckmann: {
|
||||
/* Beckmann distribution function for Gaussian random surfaces */
|
||||
const Float ex = Frame::tanTheta(m) / alphaU;
|
||||
result = std::exp(-(ex*ex)) / (M_PI * alphaU*alphaU *
|
||||
result = std::fastexp(-(ex*ex)) / (M_PI * alphaU*alphaU *
|
||||
std::pow(Frame::cosTheta(m), (Float) 4.0f));
|
||||
}
|
||||
break;
|
||||
|
@ -244,7 +244,7 @@ public:
|
|||
|
||||
switch (m_type) {
|
||||
case EBeckmann: {
|
||||
Float tanThetaMSqr = -alphaU*alphaU * std::log(1.0f - sample.x);
|
||||
Float tanThetaMSqr = -alphaU*alphaU * std::fastlog(1.0f - sample.x);
|
||||
cosThetaM = 1.0f / std::sqrt(1 + tanThetaMSqr);
|
||||
}
|
||||
break;
|
||||
|
@ -310,7 +310,7 @@ public:
|
|||
|
||||
switch (m_type) {
|
||||
case EBeckmann: {
|
||||
Float tanThetaMSqr = -alphaU*alphaU * std::log(1.0f - sample.x);
|
||||
Float tanThetaMSqr = -alphaU*alphaU * std::fastlog(1.0f - sample.x);
|
||||
cosThetaM = 1.0f / std::sqrt(1 + tanThetaMSqr);
|
||||
Float cosThetaM2 = cosThetaM * cosThetaM,
|
||||
cosThetaM3 = cosThetaM2 * cosThetaM;
|
||||
|
|
|
@ -210,7 +210,7 @@ public:
|
|||
|
||||
Float factor2 = H.x / alphaU, factor3 = H.y / alphaV;
|
||||
Float exponent = -(factor2*factor2+factor3*factor3)/(H.z*H.z);
|
||||
Float specRef = factor1 * std::exp(exponent);
|
||||
Float specRef = factor1 * std::fastexp(exponent);
|
||||
/* Important to prevent numeric issues when evaluating the
|
||||
sampling density of the Ward model in places where it takes
|
||||
on miniscule values (Veach-MLT does this for instance) */
|
||||
|
@ -245,7 +245,7 @@ public:
|
|||
Float factor2 = H.x / alphaU, factor3 = H.y / alphaV;
|
||||
|
||||
Float exponent = -(factor2*factor2+factor3*factor3)/(H.z*H.z);
|
||||
specProb = factor1 * std::exp(exponent);
|
||||
specProb = factor1 * std::fastexp(exponent);
|
||||
}
|
||||
|
||||
if (hasDiffuse)
|
||||
|
@ -298,7 +298,7 @@ public:
|
|||
1.0f-cosPhiH*cosPhiH));
|
||||
|
||||
Float thetaH = std::atan(std::sqrt(std::max((Float) 0.0f,
|
||||
-std::log(sample.x) / (
|
||||
-std::fastlog(sample.x) / (
|
||||
(cosPhiH*cosPhiH) / (alphaU*alphaU) +
|
||||
(sinPhiH*sinPhiH) / (alphaV*alphaV)
|
||||
))));
|
||||
|
|
|
@ -265,10 +265,10 @@ public:
|
|||
Float invWeight = 1.0f;
|
||||
if (pixel.weight != 0.0f)
|
||||
invWeight = 1.0f / pixel.weight;
|
||||
avgLogLuminance += std::log(0.001f + (pixel.spec * invWeight).getLuminance());
|
||||
avgLogLuminance += std::fastlog(0.001f + (pixel.spec * invWeight).getLuminance());
|
||||
}
|
||||
}
|
||||
avgLogLuminance = std::exp(avgLogLuminance/(m_cropSize.x*m_cropSize.y));
|
||||
avgLogLuminance = std::fastexp(avgLogLuminance/(m_cropSize.x*m_cropSize.y));
|
||||
reinhardKey = m_reinhardKey / avgLogLuminance;
|
||||
reinhard = true;
|
||||
pos = 0;
|
||||
|
|
|
@ -86,6 +86,8 @@ BeamRadianceEstimator::BeamRadianceEstimator(Stream *stream, InstanceManager *ma
|
|||
}
|
||||
|
||||
void BeamRadianceEstimator::serialize(Stream *stream, InstanceManager *manager) const {
|
||||
Log(EDebug, "Serializing a BRE data structure (%s)",
|
||||
memString(m_photonCount * sizeof(BRENode)).c_str());
|
||||
stream->writeSize(m_photonCount);
|
||||
stream->writeSize(m_depth);
|
||||
stream->writeFloat(m_scaleFactor);
|
||||
|
|
|
@ -435,7 +435,7 @@ Float BlackBodySpectrum::eval(Float l) const {
|
|||
/* Watts per unit surface area (m^-2) per unit wavelength (nm^-1) per
|
||||
steradian (sr^-1) */
|
||||
const double I = (2*h*c*c) * std::pow(lambda, -5.0)
|
||||
/ ((std::exp((h/k)*c/(lambda*m_temperature)) - 1.0) * 1e9);
|
||||
/ ((std::fastexp((h/k)*c/(lambda*m_temperature)) - 1.0) * 1e9);
|
||||
|
||||
return (Float) I;
|
||||
}
|
||||
|
@ -463,7 +463,7 @@ RayleighSpectrum::RayleighSpectrum(EMode mode, Float eta, Float height) {
|
|||
/* See ``Display of the Earth Taking into Account Atmospheric Scattering'',
|
||||
* by Nishita et al., SIGGRAPH 1993 */
|
||||
Float tmp = eta * eta - 1;
|
||||
Float rho = std::exp(-height/7794.0f);
|
||||
Float rho = std::fastexp(-height/7794.0f);
|
||||
//Float Ns = <molecular number density of the standard atmosphere>;
|
||||
Float N_s = 1;
|
||||
Float K = 2 * M_PI * M_PI * tmp*tmp / (3 * N_s);
|
||||
|
|
|
@ -365,8 +365,8 @@ std::string getFQDN() {
|
|||
}
|
||||
|
||||
Float log2(Float value) {
|
||||
const Float invLn2 = (Float) 1.0f / std::log((Float) 2.0f);
|
||||
return std::log(value) * invLn2;
|
||||
const Float invLn2 = (Float) 1.0f / std::fastlog((Float) 2.0f);
|
||||
return std::fastlog(value) * invLn2;
|
||||
}
|
||||
|
||||
std::string formatString(const char *fmt, ...) {
|
||||
|
@ -703,7 +703,7 @@ Vector squareToCone(Float cosCutoff, const Point2 &sample) {
|
|||
}
|
||||
|
||||
Point2 squareToStdNormal(const Point2 &sample) {
|
||||
Float r = std::sqrt(-2 * std::log(1-sample.x)),
|
||||
Float r = std::sqrt(-2 * std::fastlog(1-sample.x)),
|
||||
phi = 2 * M_PI * sample.y;
|
||||
Point2 result;
|
||||
std::sincos(phi, &result.y, &result.x);
|
||||
|
|
|
@ -119,7 +119,7 @@ MIPMap::MIPMap(int width, int height, Spectrum *pixels,
|
|||
m_weightLut = static_cast<Float *>(allocAligned(sizeof(Float)*MIPMAP_LUTSIZE));
|
||||
for (int i=0; i<MIPMAP_LUTSIZE; ++i) {
|
||||
Float pos = (Float) i / (Float) (MIPMAP_LUTSIZE-1);
|
||||
m_weightLut[i] = std::exp(-2.0f * pos) - std::exp(-2.0f);
|
||||
m_weightLut[i] = std::fastexp(-2.0f * pos) - std::fastexp(-2.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,8 +42,8 @@ PhotonMap::PhotonMap(Stream *stream, InstanceManager *manager)
|
|||
}
|
||||
|
||||
void PhotonMap::serialize(Stream *stream, InstanceManager *manager) const {
|
||||
Log(EDebug, "Serializing a photon map (%.2f KB)",
|
||||
m_kdtree.size() * sizeof(Photon) / 1024.0f);
|
||||
Log(EDebug, "Serializing a photon map (%s)",
|
||||
memString(m_kdtree.size() * sizeof(Photon)).c_str());
|
||||
stream->writeFloat(m_scale);
|
||||
stream->writeSize(m_kdtree.size());
|
||||
stream->writeSize(m_kdtree.getDepth());
|
||||
|
|
|
@ -333,13 +333,13 @@ private:
|
|||
inline Float getDistribution(const Float *lam, const Float theta,
|
||||
const Float gamma) const {
|
||||
const Float cosGamma = std::cos(gamma);
|
||||
const Float num = ((1 + lam[0] * std::exp(lam[1] / std::cos(theta)))
|
||||
* (1 + lam[2] * std::exp(lam[3] * gamma)
|
||||
const Float num = ((1 + lam[0] * std::fastexp(lam[1] / std::cos(theta)))
|
||||
* (1 + lam[2] * std::fastexp(lam[3] * gamma)
|
||||
+ lam[4] * cosGamma * cosGamma));
|
||||
|
||||
const Float cosTheta = std::cos(m_thetaS);
|
||||
const Float den = ( (1 + lam[0] * std::exp(lam[1] /* / cos 0 */))
|
||||
* (1 + lam[2] * std::exp(lam[3] * m_thetaS)
|
||||
const Float den = ( (1 + lam[0] * std::fastexp(lam[1] /* / cos 0 */))
|
||||
* (1 + lam[2] * std::fastexp(lam[3] * m_thetaS)
|
||||
+ lam[4] * cosTheta * cosTheta));
|
||||
|
||||
return num / den;
|
||||
|
|
|
@ -190,7 +190,7 @@ Spectrum computeSunRadiance(Float theta, Float turbidity) {
|
|||
for(i = 0, lambda = 350; i < 91; i++, lambda+=5) {
|
||||
// Rayleigh Scattering
|
||||
// Results agree with the graph (pg 115, MI) */
|
||||
Float tauR = std::exp(-m * 0.008735f * std::pow(lambda/1000.0f, (Float) -4.08));
|
||||
Float tauR = std::fastexp(-m * 0.008735f * std::pow(lambda/1000.0f, (Float) -4.08));
|
||||
|
||||
// Aerosal (water + dust) attenuation
|
||||
// beta - amount of aerosols present
|
||||
|
@ -203,18 +203,18 @@ Spectrum computeSunRadiance(Float theta, Float turbidity) {
|
|||
// lOzone - amount of ozone in cm(NTP)
|
||||
// Results agree with the graph (pg 128, MI)
|
||||
const Float lOzone = .35f;
|
||||
Float tauO = std::exp(-m * k_oCurve.eval(lambda) * lOzone);
|
||||
Float tauO = std::fastexp(-m * k_oCurve.eval(lambda) * lOzone);
|
||||
|
||||
// Attenuation due to mixed gases absorption
|
||||
// Results agree with the graph (pg 131, MI)
|
||||
Float tauG = std::exp(-1.41f * k_gCurve.eval(lambda) * m / std::pow(1 + 118.93f
|
||||
Float tauG = std::fastexp(-1.41f * k_gCurve.eval(lambda) * m / std::pow(1 + 118.93f
|
||||
* k_gCurve.eval(lambda) * m, (Float) 0.45f));
|
||||
|
||||
// Attenuation due to water vapor absorbtion
|
||||
// w - precipitable water vapor in centimeters (standard = 2)
|
||||
// Results agree with the graph (pg 132, MI)
|
||||
const Float w = 2.0;
|
||||
Float tauWA = std::exp(-0.2385f * k_waCurve.eval(lambda) * w * m /
|
||||
Float tauWA = std::fastexp(-0.2385f * k_waCurve.eval(lambda) * w * m /
|
||||
std::pow(1 + 20.07f * k_waCurve.eval(lambda) * w * m, (Float) 0.45f));
|
||||
|
||||
data[i] = (Float) 100.0f * solCurve.eval(lambda) * tauR * tauA * tauO * tauG * tauWA;
|
||||
|
|
|
@ -330,7 +330,7 @@ public:
|
|||
+ lookupDensity(pLast, ray.d);
|
||||
|
||||
#if defined(HETVOL_EARLY_EXIT)
|
||||
const Float stopAfterDensity = -std::log(Epsilon);
|
||||
const Float stopAfterDensity = -std::fastlog(Epsilon);
|
||||
const Float stopValue = stopAfterDensity*3.0f/(stepSize
|
||||
* m_densityMultiplier);
|
||||
#endif
|
||||
|
@ -541,7 +541,7 @@ public:
|
|||
|
||||
Spectrum getTransmittance(const Ray &ray, Sampler *sampler) const {
|
||||
if (m_method == ESimpsonQuadrature || sampler == NULL) {
|
||||
return Spectrum(std::exp(-integrateDensity(ray)));
|
||||
return Spectrum(std::fastexp(-integrateDensity(ray)));
|
||||
} else {
|
||||
/* When Woodcock tracking is selected as the sampling method,
|
||||
we can use this method to get a noisy estimate of
|
||||
|
@ -561,7 +561,7 @@ public:
|
|||
for (int i=0; i<nSamples; ++i) {
|
||||
Float t = mint;
|
||||
while (true) {
|
||||
t -= std::log(1-sampler->next1D()) * m_invMaxDensity;
|
||||
t -= std::fastlog(1-sampler->next1D()) * m_invMaxDensity;
|
||||
if (t >= maxt) {
|
||||
result += 1;
|
||||
break;
|
||||
|
@ -588,7 +588,7 @@ public:
|
|||
bool success = false;
|
||||
|
||||
if (m_method == ESimpsonQuadrature) {
|
||||
Float desiredDensity = -std::log(1-sampler->next1D());
|
||||
Float desiredDensity = -std::fastlog(1-sampler->next1D());
|
||||
if (invertDensityIntegral(ray, desiredDensity, integratedDensity,
|
||||
mRec.t, densityAtMinT, densityAtT)) {
|
||||
mRec.p = ray(mRec.t);
|
||||
|
@ -601,7 +601,7 @@ public:
|
|||
? m_orientation->lookupVector(mRec.p) : Vector(0.0f);
|
||||
}
|
||||
|
||||
Float expVal = std::exp(-integratedDensity);
|
||||
Float expVal = std::fastexp(-integratedDensity);
|
||||
mRec.pdfFailure = expVal;
|
||||
mRec.pdfSuccess = expVal * densityAtT;
|
||||
mRec.pdfSuccessRev = expVal * densityAtMinT;
|
||||
|
@ -626,7 +626,7 @@ public:
|
|||
|
||||
Float t = mint, densityAtT = 0;
|
||||
while (true) {
|
||||
t -= std::log(1-sampler->next1D()) * m_invMaxDensity;
|
||||
t -= std::fastlog(1-sampler->next1D()) * m_invMaxDensity;
|
||||
if (t >= maxt)
|
||||
break;
|
||||
|
||||
|
@ -656,7 +656,7 @@ public:
|
|||
|
||||
void pdfDistance(const Ray &ray, MediumSamplingRecord &mRec) const {
|
||||
if (m_method == ESimpsonQuadrature) {
|
||||
Float expVal = std::exp(-integrateDensity(ray));
|
||||
Float expVal = std::fastexp(-integrateDensity(ray));
|
||||
|
||||
mRec.transmittance = Spectrum(expVal);
|
||||
mRec.pdfFailure = expVal;
|
||||
|
|
|
@ -250,7 +250,7 @@ public:
|
|||
Spectrum transmittance;
|
||||
for (size_t i=0; i<SPECTRUM_SAMPLES; ++i)
|
||||
transmittance[i] = m_sigmaT[i] != 0
|
||||
? std::exp(m_sigmaT[i] * negLength) : (Float) 1.0f;
|
||||
? std::fastexp(m_sigmaT[i] * negLength) : (Float) 1.0f;
|
||||
return transmittance;
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ public:
|
|||
* SPECTRUM_SAMPLES), SPECTRUM_SAMPLES-1);
|
||||
samplingDensity = m_sigmaT[channel];
|
||||
}
|
||||
sampledDistance = -std::log(1-rand) / samplingDensity;
|
||||
sampledDistance = -std::fastlog(1-rand) / samplingDensity;
|
||||
} else {
|
||||
sampledDistance = m_maxExpDist->sample(1-rand, mRec.pdfSuccess);
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ public:
|
|||
mRec.pdfFailure = 0;
|
||||
mRec.pdfSuccess = 0;
|
||||
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
||||
Float tmp = std::exp(-m_sigmaT[i] * sampledDistance);
|
||||
Float tmp = std::fastexp(-m_sigmaT[i] * sampledDistance);
|
||||
mRec.pdfFailure += tmp;
|
||||
mRec.pdfSuccess += m_sigmaT[i] * tmp;
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ public:
|
|||
|
||||
case ESingle:
|
||||
case EManual:
|
||||
mRec.pdfFailure = std::exp(-samplingDensity * sampledDistance);
|
||||
mRec.pdfFailure = std::fastexp(-samplingDensity * sampledDistance);
|
||||
mRec.pdfSuccess = samplingDensity * mRec.pdfFailure;
|
||||
break;
|
||||
|
||||
|
@ -329,7 +329,7 @@ public:
|
|||
switch (m_strategy) {
|
||||
case EManual:
|
||||
case ESingle: {
|
||||
Float temp = std::exp(-m_samplingDensity * distance);
|
||||
Float temp = std::fastexp(-m_samplingDensity * distance);
|
||||
mRec.pdfSuccess = m_samplingDensity * temp;
|
||||
mRec.pdfFailure = temp;
|
||||
}
|
||||
|
@ -339,7 +339,7 @@ public:
|
|||
mRec.pdfSuccess = 0;
|
||||
mRec.pdfFailure = 0;
|
||||
for (int i=0; i<SPECTRUM_SAMPLES; ++i) {
|
||||
Float temp = std::exp(-m_sigmaT[i] * distance);
|
||||
Float temp = std::fastexp(-m_sigmaT[i] * distance);
|
||||
mRec.pdfSuccess += m_sigmaT[i] * temp;
|
||||
mRec.pdfFailure += temp;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
|
||||
/* Store the interval covered by each f_i */
|
||||
m_intervalStart[i] = (i == 0) ? 0
|
||||
: std::log(m_sigmaT[i]/m_sigmaT[i-1]) / (m_sigmaT[i]-m_sigmaT[i-1]);
|
||||
: std::fastlog(m_sigmaT[i]/m_sigmaT[i-1]) / (m_sigmaT[i]-m_sigmaT[i-1]);
|
||||
}
|
||||
|
||||
/* Turn into a discrete CDF and keep the normalization factor */
|
||||
|
@ -59,11 +59,11 @@ public:
|
|||
SAssert(index >= 0 && index < (int) m_sigmaT.size());
|
||||
|
||||
/* Sample according to f_i */
|
||||
Float t = -std::log(std::exp(-m_intervalStart[index] * m_sigmaT[index])
|
||||
Float t = -std::fastlog(std::fastexp(-m_intervalStart[index] * m_sigmaT[index])
|
||||
- m_normalization * (u - m_cdf[index])) / m_sigmaT[index];
|
||||
|
||||
/* Compute the probability of this sample */
|
||||
pdf = m_sigmaT[index] * std::exp(-m_sigmaT[index] * t) * m_invNormalization;
|
||||
pdf = m_sigmaT[index] * std::fastexp(-m_sigmaT[index] * t) * m_invNormalization;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public:
|
|||
&m_intervalStart[m_intervalStart.size()], t);
|
||||
int index = std::max(0, (int) (lowerBound - &m_intervalStart[0]) - 1);
|
||||
SAssert(index >= 0 && index < (int) m_sigmaT.size());
|
||||
return m_sigmaT[index] * std::exp(-m_sigmaT[index] * t) * m_invNormalization;
|
||||
return m_sigmaT[index] * std::fastexp(-m_sigmaT[index] * t) * m_invNormalization;
|
||||
}
|
||||
|
||||
Float cdf(Float t) const {
|
||||
|
@ -84,7 +84,7 @@ public:
|
|||
|
||||
Float lower = (index==0) ? -1 : -std::pow((m_sigmaT[index]/m_sigmaT[index-1]),
|
||||
-m_sigmaT[index] / (m_sigmaT[index]-m_sigmaT[index-1]));
|
||||
Float upper = -std::exp(-m_sigmaT[index] * t);
|
||||
Float upper = -std::fastexp(-m_sigmaT[index] * t);
|
||||
|
||||
return m_cdf[index] + (upper - lower) * m_invNormalization;
|
||||
}
|
||||
|
|
|
@ -850,7 +850,7 @@ Float GLWidget::autoFocus() const {
|
|||
radicalInverse(3, sampleIndex) * filmSize.y);
|
||||
scene->getCamera()->generateRay(sample, Point2(0, 0), 0, ray);
|
||||
if (scene->rayIntersect(ray, t, ptr, n)) {
|
||||
Float weight = std::exp(-0.5 / variance * (
|
||||
Float weight = std::fastexp(-0.5 / variance * (
|
||||
std::pow(sample.x - filmSize.x / (Float) 2, (Float) 2) +
|
||||
std::pow(sample.y - filmSize.y / (Float) 2, (Float) 2)));
|
||||
avgDistance += t * weight;
|
||||
|
@ -1101,7 +1101,7 @@ void GLWidget::paintGL() {
|
|||
m_downsamplingProgram->unbind();
|
||||
Float logLuminance, maxLuminance, unused;
|
||||
m_luminanceBuffer[target]->getPixel(0, 0).toLinearRGB(logLuminance, maxLuminance, unused);
|
||||
logLuminance = std::exp(logLuminance / (size.x*size.y));
|
||||
logLuminance = std::fastexp(logLuminance / (size.x*size.y));
|
||||
if (mts_isnan(logLuminance) || std::isinf(logLuminance)) {
|
||||
SLog(EWarn, "Could not determine the average log-luminance, since the image contains NaNs/infs/negative values");
|
||||
logLuminance = 1;
|
||||
|
|
|
@ -1369,10 +1369,10 @@ void MainWindow::onExportDialogClose(int reason) {
|
|||
Spectrum spec;
|
||||
spec.fromLinearRGB(source[(y*width+x)*4+0],
|
||||
source[(y*width+x)*4+1], source[(y*width+x)*4+2]);
|
||||
avgLogLuminance += std::log(0.001f+spec.getLuminance());
|
||||
avgLogLuminance += std::fastlog(0.001f+spec.getLuminance());
|
||||
}
|
||||
}
|
||||
avgLogLuminance = std::exp(avgLogLuminance/(width*height));
|
||||
avgLogLuminance = std::fastexp(avgLogLuminance/(width*height));
|
||||
reinhardKey = ctx->reinhardKey / avgLogLuminance;
|
||||
}
|
||||
|
||||
|
|
|
@ -242,13 +242,13 @@ public:
|
|||
|
||||
/// Evaluate the density as a function of \cos\theta
|
||||
inline Float pdfCosTheta(Float cosTheta) const {
|
||||
return std::exp(-cosTheta*cosTheta
|
||||
return std::fastexp(-cosTheta*cosTheta
|
||||
/ (2*m_stddev*m_stddev)) * m_normalization;
|
||||
}
|
||||
|
||||
/// Evaluate the density as a function of direction
|
||||
inline Float pdf(const Vector &d) const {
|
||||
return std::exp(-d.z*d.z
|
||||
return std::fastexp(-d.z*d.z
|
||||
/ (2*m_stddev*m_stddev)) * m_normalization;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
m_size = Vector2(halfSize, halfSize);
|
||||
|
||||
/* Negative offset pre-computation */
|
||||
m_const = std::exp(-m_alpha * m_size.x * m_size.x);
|
||||
m_const = std::fastexp(-m_alpha * m_size.x * m_size.x);
|
||||
}
|
||||
|
||||
GaussianFilter(Stream *stream, InstanceManager *manager)
|
||||
|
@ -61,8 +61,8 @@ public:
|
|||
}
|
||||
|
||||
Float evaluate(Float x, Float y) const {
|
||||
return std::max((Float) 0.0f, std::exp(-m_alpha * x * x) - m_const)
|
||||
* std::max((Float) 0.0f, std::exp(-m_alpha * y * y) - m_const);
|
||||
return std::max((Float) 0.0f, std::fastexp(-m_alpha * x * x) - m_const)
|
||||
* std::max((Float) 0.0f, std::fastexp(-m_alpha * y * y) - m_const);
|
||||
}
|
||||
|
||||
MTS_DECLARE_CLASS()
|
||||
|
|
|
@ -71,8 +71,8 @@ struct AnisotropicDipoleQuery {
|
|||
Float zr = -xr[i].z, zv = xv[i].z;
|
||||
|
||||
temp[i] = detP[i]/(4*M_PI) * (
|
||||
zr*(beta[i]*dr+1)*std::exp(-beta[i]*dr)/(dr*dr*dr) +
|
||||
zv*(beta[i]*dv+1)*std::exp(-beta[i]*dv)/(dv*dv*dv)
|
||||
zr*(beta[i]*dr+1)*std::fastexp(-beta[i]*dr)/(dr*dr*dr) +
|
||||
zv*(beta[i]*dv+1)*std::fastexp(-beta[i]*dv)/(dv*dv*dv)
|
||||
);
|
||||
}
|
||||
dMo.fromLinearRGB(temp[0], temp[1], temp[2]);
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
}
|
||||
|
||||
inline Float gauss3(Vector x, Float stddev) const {
|
||||
return std::exp(-0.5f * dot(x, x)/stddev)/(std::pow(2*M_PI * stddev, (Float) 3 / (Float) 2));
|
||||
return std::fastexp(-0.5f * dot(x, x)/stddev)/(std::pow(2*M_PI * stddev, (Float) 3 / (Float) 2));
|
||||
}
|
||||
|
||||
void testF3(size_t nPoints, const Float *in, Float *out) const {
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
for (int i=0; i<(int) nPts; ++i) {
|
||||
Vector d = sphericalDirection(in[2*i], in[2*i+1]);
|
||||
Float sinTheta = std::sin(in[2*i]);
|
||||
Float D = sinTheta * std::exp(-std::pow(d.z, 2)/(2*m_gamma*m_gamma)) /
|
||||
Float D = sinTheta * std::fastexp(-std::pow(d.z, 2)/(2*m_gamma*m_gamma)) /
|
||||
(std::pow(2*M_PI, (Float) 3 / (Float) 2) * m_gamma * erf(1/(std::sqrt(2)*m_gamma)));
|
||||
for (size_t j=0; j<m_res; ++j)
|
||||
out[j*nPts+i] = D * absDot(d, m_directions[j]);
|
||||
|
|
Loading…
Reference in New Issue