Skip to content

Restore branchless 'and' operations [15_0_X] #47875

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CommonTools/RecoAlgos/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<use name="SimGeneral/HepPDTRecord"/>
<use name="FWCore/Framework"/>
<use name="FWCore/ParameterSet"/>
<use name="DataFormats/Math"/>
<use name="DataFormats/TrackReco"/>
<use name="DataFormats/MuonReco"/>
<use name="DataFormats/TrackingRecHit"/>
Expand Down
4 changes: 3 additions & 1 deletion CommonTools/RecoAlgos/interface/KDTreeLinkerAlgo.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef KDTreeLinkerAlgoTemplated_h
#define KDTreeLinkerAlgoTemplated_h

#include "DataFormats/Math/interface/logic.h"

#include <cassert>
#include <vector>
#include <array>
Expand Down Expand Up @@ -229,7 +231,7 @@ void KDTreeLinkerAlgo<DATA, DIM>::recSearch(int current, const KDTreeBox<DIM> &t
bool isInside = true;
for (unsigned i = 0; i < DIM; ++i) {
float dimCurr = nodePool_.dims[i][current];
isInside &= (dimCurr >= trackBox.dimmin[i]) && (dimCurr <= trackBox.dimmax[i]);
isInside &= reco::branchless_and(dimCurr >= trackBox.dimmin[i], dimCurr <= trackBox.dimmax[i]);
}
if (isInside) {
closestNeighbour->push_back(nodePool_.data[current]);
Expand Down
13 changes: 13 additions & 0 deletions DataFormats/Math/interface/logic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef DataFormats_Math_logic_h
#define DataFormats_Math_logic_h

namespace reco {
// this function can be called with any boolean expressions as the parameters
// this forces the evaluation of both expressions (faster if the expressions are simple)
// and applying && to two bools avoids branching (jump instruction)
// whereas applying && to the two original expressions may cause branching
// this is an alternative to using the bitwise and operator (&), which never short-circuits
inline bool branchless_and(bool a, bool b) { return a && b; }
} // namespace reco

#endif
1 change: 1 addition & 0 deletions RecoTracker/MeasurementDet/BuildFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<use name="TrackingTools/GeomPropagators"/>
<use name="CalibFormats/SiStripObjects"/>
<use name="DataFormats/Common"/>
<use name="DataFormats/Math"/>
<use name="DataFormats/SiPixelCluster"/>
<use name="FWCore/Framework"/>
<use name="FWCore/ParameterSet"/>
Expand Down
3 changes: 2 additions & 1 deletion RecoTracker/MeasurementDet/plugins/doubleMatch.icc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ namespace {
#include "RecHitPropagator.h"
#include "DataFormats/GeometrySurface/interface/RectangularPlaneBounds.h"
#include "DataFormats/GeometrySurface/interface/LocalError.h"
#include "DataFormats/Math/interface/logic.h"

namespace {
inline void print(const char* where, const TrajectoryStateOnSurface& t1, const TrajectoryStateOnSurface& t2) {
Expand Down Expand Up @@ -128,7 +129,7 @@ void TkGluedMeasurementDet::doubleMatch(const TrajectoryStateOnSurface& ts,
return;
}

if ((!monoHits.empty()) && (!stereoHits.empty())) {
if (reco::branchless_and(!monoHits.empty(), !stereoHits.empty())) {
const GluedGeomDet* gluedDet = &specificGeomDet();
LocalVector trdir = (ts.isValid() ? ts.localDirection() : surface().toLocal(position() - GlobalPoint(0, 0, 0)));

Expand Down