diff --git a/.gitea/workflows/build_and_test.yml b/.gitea/workflows/build_and_test.yml index 661e08d5..07d27f5e 100644 --- a/.gitea/workflows/build_and_test.yml +++ b/.gitea/workflows/build_and_test.yml @@ -2,6 +2,10 @@ name: Build Packages env: MARCH_CMAKE_FLAGS: '-DCMAKE_CXX_FLAGS="-march=x86-64-v3" -DCMAKE_C_FLAGS="-march=x86-64-v3"' + # MSVC has no spelling for the x86-64-v2 level; /arch:AVX is the nearest and implies SSE4.1/4.2, + # which is what matters here - without it Eigen has no vectorised round and falls back to a libm + # call per element. AVX is Sandy Bridge (2011) and up, a safe floor for a desktop viewer. + MSVC_ARCH_CMAKE_FLAGS: '-DCMAKE_CXX_FLAGS="/arch:AVX" -DCMAKE_C_FLAGS="/arch:AVX"' on: push: @@ -83,7 +87,7 @@ jobs: run: | for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath`) do set "VSPATH=%%i" call "%VSPATH%\VC\Auxiliary\Build\vcvars64.bat" - cmake -G Ninja -B build -DJFJOCH_USE_CUDA=${{ matrix.use_cuda }} -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="C:/deps;C:/Qt/6.11.1/msvc2022_64" + cmake -G Ninja -B build -DJFJOCH_USE_CUDA=${{ matrix.use_cuda }} -DCMAKE_BUILD_TYPE=Release ${{ env.MSVC_ARCH_CMAKE_FLAGS }} -DCMAKE_PREFIX_PATH="C:/deps;C:/Qt/6.11.1/msvc2022_64" - name: Build viewer shell: cmd run: | diff --git a/CLAUDE.md b/CLAUDE.md index 3ea9c517..c043d8ec 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -43,6 +43,27 @@ Key CMake options: - `SLS9` (default OFF) — build against slsDetectorPackage 9.2.0 instead of 8.0.2. - `JFJOCH_INSTALL_DRIVER_SOURCE` (default OFF) — install the PCIe driver source for DKMS/RPM. +### `-march` is deliberately NOT set in CMakeLists + +The build system sets no architecture flags, so a site can pick its own — `x86-64-v4` on an +AVX-512 cluster, `-march=native`, or the plain baseline. **CI passes them explicitly** +(`.gitea/workflows/build_and_test.yml`): every Linux configure gets +`-march=x86-64-v3`, and the MSVC viewer job gets `/arch:AVX` (MSVC has no x86-64-v2 spelling; +`/arch:AVX` is the nearest and implies SSE4.1/4.2). + +**This matters when profiling.** A plain `cmake -DCMAKE_BUILD_TYPE=Release ..` produces a +*baseline* binary that is not what CI or production runs, and the difference is not uniform: +GPU-bound work is unaffected, but the CPU/Eigen-bound phases — first-pass indexing and +scaling/merging — are **~26% slower** without the flags (measured). Eigen in particular has no +vectorised `round` below SSE4.1 and falls back to a libm call per element, which can make +rounding look like ~10% of all cycles when it is nearly free in a real build. Pass the CI flags +when measuring anything CPU-side, or the profile will point at the wrong code: + +``` +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-march=x86-64-v3" \ + -DCMAKE_C_FLAGS="-march=x86-64-v3" .. +``` + The frontend is a separate custom target: `make frontend` (in `frontend/`: `npm ci`, `npm run build`, plus the third-party-licenses, Redoc and Sphinx-docs bundling steps). It is never built automatically — `make install` only copies whatever already sits in `frontend/dist/`.