Один очевидный вопрос: какая бесконечность вам нужна, когда ввод меньше 0.
Любая бесконечность
Если результат может быть отрицательной бесконечностью, я 'd сделать что-то вроде этого:
coeffs[i] /= (coeffs[i] >= 0.0);
coeffs[i] >= 0.0
выдает 1,0, если вход положительный, и 0.0
, если вход отрицательный.Деление ввода на 1,0 оставляет его без изменений.Разделив его на 0, мы получим бесконечность.
Положительная бесконечность
Если это положительная бесконечность, вы бы изменили ее на что-то вроде:
coeffs[i] = (fabs(coeffs[i]) / (coeffs[i] >= 0.0);
Взявабсолютное значение перед делением, бесконечность, которую мы производим для отрицательного, вынуждена быть положительной.В противном случае входные данные начинались с положительного значения, поэтому fabs
и деление на 1,0 оставляют значение без изменений.
Производительность
Что касается того, действительно ли это улучшит производительность, то это, вероятно, открыто для многихеще вопрос.На данный момент, давайте посмотрим на код для процессора, так как Godbolt позволяет нам исследовать это довольно легко.
Если мы посмотрим на это:
#include <limits>
double f(double in) {
return in / (in >= 0.0);
}
double g(double in) {
return in > 0.0 ? in : std::numeric_limits<double>::infinity();
}
Итак, давайте посмотрим на полученный коддля первой функции:
xorpd xmm1, xmm1
cmplesd xmm1, xmm0
movsd xmm2, qword ptr [rip + .LCPI0_0] # xmm2 = mem[0],zero
andpd xmm2, xmm1
divsd xmm0, xmm2
ret
Так что это не так уж и страшно - без ответвлений и (в зависимости от используемого процессора) пропускная способность около 8-10 циклов на наиболее разумныхсовременные процессоры.С другой стороны, вот код, созданный для второй функции:
xorpd xmm1, xmm1
cmpltsd xmm1, xmm0
andpd xmm0, xmm1
movsd xmm2, qword ptr [rip + .LCPI1_0] # xmm2 = mem[0],zero
andnpd xmm1, xmm2
orpd xmm0, xmm1
ret
Это также без веток - и у него нет этой (относительно медленной) инструкции divsd.Опять же, производительность будет варьироваться в зависимости от конкретного процессора, но мы можем, вероятно, планировать, что пропускная способность будет около 6 циклов или около того - не значительно быстрее, чем предыдущий, но, вероятно, по крайней мере на несколько циклов быстреевремени, и почти наверняка никогда не будет медленнее.Короче говоря, это, вероятно, предпочтительнее почти для любого возможного процессора.
Код графического процессора
Графические процессоры, конечно, имеют свои собственные наборы инструкций - но с учетом штрафа, который они несут за ветки, компиляторы для них (и наборы инструкций, которые они предоставляют), вероятно, делают, по крайней мере, столько же, чтобы помочь устранить ветки, что и процессоры, так что есть вероятность, что простой код также будет хорошо работать на нем (хотя, чтобы сказать с уверенностью, вам придется либо исследоватькод, который он произвел или профилировать его).