forked from animatedread/Warrior_EA
Measured on this machine's actual CPU at the real 760-wide geometry, through a real DLL boundary (an earlier harness #included the .cpp and the fast-math build hoisted the timing loop, reporting a flat ~4us for shapes 8x apart). Every hot kernel is a floating-point reduction. Under the default /fp:precise MSVC may not reassociate one, so it cannot vectorize one - the dot product was scalar mulsd/addsd through a single accumulator. Forward pass measured 1.1-1.9 GFLOP/s precise vs 1.7-2.8 GFLOP/s fast, and the same three neurons*inputs loops (forward, hidden gradient, weight-gradient accumulate) dominate an era. batch_accum_check passes on both builds with identical output to every digit it prints, including the 5-decade optimizer scale-invariance sweep. The deploy-time CPU-vs-MQL5 self-check tolerance is 1.0e-3, ~11 orders looser than fast-math drift. /arch:AVX2 is now explicitly forbidden in the script with the reason. This CPU is an Ivy Bridge-EP Xeon: AVX yes, AVX2/FMA no. An AVX2 build faults on every kernel, SehCallFn swallows it per dispatch, buffers are never written, and every shape takes a flat ~5us - which benchmarks as a 250x speedup until you check that the outputs are all zero. /arch:AVX alone was measured and bought nothing; these loops are memory-bound and Ivy Bridge splits 256-bit loads into 2x128 anyway. Requires rebuilding WarriorCPU.dll (build_cpu.bat) - the .ex5 is unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
83 lines
3.5 KiB
Batchfile
83 lines
3.5 KiB
Batchfile
@echo off
|
|
REM Builds WarriorCPU.dll with MSVC. Run this from a plain cmd/PowerShell
|
|
REM window - it locates and loads the VS build environment itself, no
|
|
REM need to open a "Developer Command Prompt" first.
|
|
setlocal
|
|
|
|
set VSWHERE="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
|
|
if not exist %VSWHERE% (
|
|
echo Could not find vswhere.exe - is Visual Studio / Build Tools installed?
|
|
exit /b 1
|
|
)
|
|
|
|
for /f "usebackq tokens=*" %%i in (`%VSWHERE% -latest -products * -property installationPath`) do (
|
|
set VSINSTALL=%%i
|
|
)
|
|
if not defined VSINSTALL (
|
|
echo Could not find any Visual Studio / Build Tools installation.
|
|
exit /b 1
|
|
)
|
|
if not exist "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat" (
|
|
echo Found a VS install at "%VSINSTALL%" but it has no C++ toolset ^(vcvars64.bat missing^).
|
|
echo Install the "Desktop development with C++" workload ^(or the smaller
|
|
echo "Build Tools for Visual Studio"^) and re-run this script.
|
|
exit /b 1
|
|
)
|
|
|
|
call "%VSINSTALL%\VC\Auxiliary\Build\vcvars64.bat"
|
|
if errorlevel 1 exit /b 1
|
|
|
|
cd /d "%~dp0"
|
|
REM ---------------------------------------------------------------------------
|
|
REM /fp:fast is load-bearing, not cosmetic. Every hot kernel in WarriorCPU.cpp
|
|
REM is a floating-point REDUCTION (`sum += in[k] * w[shift+k]` and friends).
|
|
REM Under the default /fp:precise the compiler may not reassociate a reduction,
|
|
REM so it cannot vectorize one either - the dot product compiles to scalar
|
|
REM mulsd/addsd chained through a single accumulator, one double at a time.
|
|
REM Measured on the Xeon E5-1650 v2 this trains on, at the real 760-wide
|
|
REM geometry: 1.1-1.9 GFLOP/s precise vs 1.7-2.8 GFLOP/s fast, i.e. ~1.5-2x on
|
|
REM the three neurons*inputs MAC loops that dominate a training era (forward,
|
|
REM hidden gradient, weight-gradient accumulate).
|
|
REM Verified safe by DirectML\batch_accum_check.bat: every check passes with
|
|
REM byte-identical output to the /fp:precise build, and the deploy-time
|
|
REM CPU-vs-MQL5 self-check tolerance (CPU_INFERENCE_MAX_DIFF) is 1.0e-3, some
|
|
REM eleven orders of magnitude looser than the drift fast-math can introduce.
|
|
REM
|
|
REM DO NOT ADD /arch:AVX2. This machine's CPU (Ivy Bridge-EP, 2013) has AVX but
|
|
REM NOT AVX2 or FMA, so an AVX2 build turns every kernel into an illegal
|
|
REM instruction. That failure is SILENT and looks like success: SehCallFn
|
|
REM catches the fault per dispatch, the kernel returns 0, buffers stay
|
|
REM untouched, and every shape takes a flat ~5us regardless of size - which
|
|
REM benchmarks as a 250x "speedup" until you notice the outputs are all zero.
|
|
REM /arch:AVX alone was measured too and bought nothing (these loops are
|
|
REM memory-bound, and Ivy Bridge splits 256-bit loads into 2x128 internally).
|
|
REM ---------------------------------------------------------------------------
|
|
cl.exe /nologo /LD /EHsc /O2 /fp:fast /std:c++17 ^
|
|
WarriorCPU.cpp ^
|
|
/Fe:WarriorCPU.dll
|
|
|
|
if errorlevel 1 (
|
|
echo Build failed.
|
|
exit /b 1
|
|
)
|
|
|
|
set "TARGET_ROOT=%APPDATA%\MetaQuotes"
|
|
if exist "%TARGET_ROOT%\Terminal" (
|
|
for /d %%D in ("%TARGET_ROOT%\Terminal\*") do (
|
|
if exist "%%~fD\MQL5\Libraries" (
|
|
copy /Y "%~dp0WarriorCPU.dll" "%%~fD\MQL5\Libraries\WarriorCPU.dll" >nul 2>&1
|
|
)
|
|
)
|
|
)
|
|
if exist "%TARGET_ROOT%\Tester" (
|
|
for /d %%D in ("%TARGET_ROOT%\Tester\*") do (
|
|
if exist "%%~fD\MQL5\Libraries" (
|
|
copy /Y "%~dp0WarriorCPU.dll" "%%~fD\MQL5\Libraries\WarriorCPU.dll" >nul 2>&1
|
|
)
|
|
)
|
|
)
|
|
|
|
echo.
|
|
echo Built DirectML\WarriorCPU.dll
|
|
echo Deployed to any discovered MetaTrader MQL5\Libraries folders.
|
|
endlocal
|