CookProcessCount

CookProcessCount

#Overview

name: CookProcessCount

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

It is referenced in 5 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of CookProcessCount is to determine the number of cooking processes to be used in Unreal Engine’s content cooking system. It is primarily used to configure and control multi-process cooking, which can significantly speed up the content preparation process for game deployments.

This setting variable is mainly relied upon by the Unreal Engine’s cooking system, specifically within the UCookOnTheFlyServer and UE::Cook::FCookDirector classes. These are part of the UnrealEd module, which is responsible for editor-time functionalities including content cooking.

The value of CookProcessCount is set through multiple potential sources, in order of priority:

  1. Command line argument: “-CookProcessCount=”
  2. If launched by the editor, from the GEditorIni file under [CookSettings] with key “CookProcessCountFromEditor”
  3. From the GEditorIni file under [CookSettings] with key “CookProcessCount”

If not set or set to a negative value, it defaults to 1.

This variable interacts closely with the CookDirector system. When CookProcessCount is greater than 1, a UE::Cook::FCookDirector is created to manage multiple cooking processes.

Developers should be aware that:

  1. Setting CookProcessCount to 1 or lower disables multi-process cooking.
  2. The actual number of worker processes is CookProcessCount - 1, as one process is the director.
  3. Multi-process cooking may not be available on all platforms or configurations.

Best practices when using this variable include:

  1. Consider the available system resources when setting this value. More processes aren’t always better if they exceed available CPU cores or memory.
  2. Test different values to find the optimal setting for your specific project and hardware.
  3. Be aware that enabling multi-process cooking (CookProcessCount > 1) may change behavior or expose different issues compared to single-process cooking.
  4. When debugging cooking issues, consider testing with CookProcessCount set to 1 to eliminate multi-process complexities.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEditor.ini:389, section: [CookSettings]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:6745

Scope (from outer to inner):

file
function     void UCookOnTheFlyServer::Initialize

Source code excerpt:

	{
		bool bLaunchedByEditor = !FPlatformMisc::GetEnvironmentVariable(GEditorUIPidVariable).IsEmpty();
		int32 CookProcessCount=-1;
		FParse::Value(FCommandLine::Get(), TEXT("-CookProcessCount="), CookProcessCount);
		if (CookProcessCount < 0 && bLaunchedByEditor)
		{
			GConfig->GetInt(TEXT("CookSettings"), TEXT("CookProcessCountFromEditor"), CookProcessCount, GEditorIni);
		}
		if (CookProcessCount < 0)
		{
			GConfig->GetInt(TEXT("CookSettings"), TEXT("CookProcessCount"), CookProcessCount, GEditorIni);
		}
		CookProcessCount = FMath::Max(1, CookProcessCount);
		if (CookProcessCount > 1)
		{
			CookDirector = MakeUnique<UE::Cook::FCookDirector>(*this, CookProcessCount);
			if (!CookDirector->IsMultiprocessAvailable())
			{
				CookDirector.Reset();
			}
		}
		else
		{
			UE_LOG(LogCook, Display, TEXT("CookProcessCount=%d. CookMultiprocess is disabled and the cooker is running as a single process."),
				CookProcessCount);
		}
	}

	UE::Cook::InitializeTls();
	UE::Cook::FPlatformManager::InitializeTls();

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookDirector.cpp:114

Scope (from outer to inner):

file
namespace    UE::Cook
function     FCookDirector::FCookDirector

Source code excerpt:

};

FCookDirector::FCookDirector(UCookOnTheFlyServer& InCOTFS, int32 CookProcessCount)
	: RunnableShunt(*this) 
	, COTFS(InCOTFS)
{
	check(CookProcessCount > 1);
	WorkersStalledStartTimeSeconds = MAX_flt;
	WorkersStalledWarnTimeSeconds = MAX_flt;
	ShutdownEvent->Reset();
	LocalWorkerProfileData = MakeUnique<FCookWorkerProfileData>();
	RetractionHandler = MakeUnique<FRetractionHandler>(*this);

	bool bConfigValid;
	ParseConfig(CookProcessCount, bConfigValid);
	if (!bConfigValid)
	{
		UE_LOG(LogCook, Error, TEXT("CookDirector initialization failure: config settings are invalid for multiprocess. CookMultiprocess is disabled and the cooker is running as a single process."));
		bMultiprocessAvailable = false;
		return;
	}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookDirector.cpp:172

Scope (from outer to inner):

file
namespace    UE::Cook
function     void FCookDirector::ParseConfig

Source code excerpt:

}

void FCookDirector::ParseConfig(int32 CookProcessCount, bool& bOutValid)
{
	bOutValid = true;
	const TCHAR* CommandLine = FCommandLine::Get();
	FString Text;

	// CookWorkerCount
	RequestedCookWorkerCount = CookProcessCount - 1;
	check(RequestedCookWorkerCount > 0);

	// CookDirectorListenPort
	WorkerConnectPort = Sockets::COOKDIRECTOR_DEFAULT_REQUEST_CONNECTION_PORT;
	FParse::Value(CommandLine, TEXT("-CookDirectorListenPort="), WorkerConnectPort);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookDirector.h:59

Scope (from outer to inner):

file
namespace    UE::Cook
class        class FCookDirector

Source code excerpt:

public:

	FCookDirector(UCookOnTheFlyServer& InCOTFS, int32 CookProcessCount);
	~FCookDirector();

	bool IsMultiprocessAvailable() const;
	void StartCook(const FBeginCookContext& Context);

	/**

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookDirector.h:142

Scope (from outer to inner):

file
namespace    UE::Cook
class        class FCookDirector

Source code excerpt:

private:
	/** Helper for constructor parsing. */
	void ParseConfig(int32 CookProcessCount, bool& bOutValid);
	/** Initialization helper: create the listen socket. */
	bool TryCreateWorkerConnectSocket();
	/**
	 * Construct CookWorkerServers and communication thread if not yet constructed.
	 * The CookWorkerServers are constructed to Uninitialized; the worker process is created later.
	 */