DECLARE @oneGb INT = 1024; -- MB

-- "hard coded" options
DECLARE @architecture NVARCHAR(10) = 'x64';
DECLARE @totalram INT = 16 * @oneGb;
DECLARE @corenumber INT = 2;
DECLARE @otherApps INT = 0; --reserved ram for other apps in Mo

-- Thread stack sizes in MB
DECLARE @threadStackSizes TABLE (Architecture NVARCHAR(10), Size INT);
INSERT INTO @threadStackSizes VALUES ('x86', 1), ('x64', 2), ('IA64', 4);

DECLARE @threadStackSize INT;
SELECT @threadStackSize = Size FROM @threadStackSizes WHERE Architecture = @architecture;

DECLARE @osReservedPart FLOAT;
SET @osReservedPart = CASE WHEN @totalram < (20 * @oneGb) THEN 0.2 ELSE 0.125 END;

DECLARE @forOS INT;
SET @forOS = CAST(@totalram * @osReservedPart AS INT);

DECLARE @coretemp INT;
SET @coretemp = CASE WHEN @corenumber > 4 THEN 0 ELSE @corenumber END;

DECLARE @sqlThreads INT;
SET @sqlThreads = 256 + (@coretemp - 4) * 8;

DECLARE @temp FLOAT;
SET @temp = @corenumber / 4.0;

DECLARE @maxMemory INT;
SET @maxMemory = @totalram - @forOS - @otherApps - (@sqlThreads * @threadStackSize) - (1024 * CEILING(@temp));

-- Display the result
SELECT @maxMemory AS 'Max Memory (MB)';
