Skip to content
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

Add parameter to configure updating page permissions in StoreToAddress #1523

Merged
merged 2 commits into from
Jul 10, 2021

Conversation

nosoop
Copy link
Contributor

@nosoop nosoop commented Jul 4, 2021

Closes #1375.

This adds a new optional parameter to StoreToAddress, allowing plugins to opt out of having SourceMod update page permissions every time it writes to memory.

Tested in TF2 with the following micro benchmark:

Micro benchmark source code:
#include <sourcemod>

#pragma semicolon 1
#pragma newdecls required

#include <profiler>

public void OnPluginStart() {
	RegAdminCmd("test_memwrite", MemWrite, ADMFLAG_ROOT);
}

#define NUM_ITERATIONS (1 << 19)

public Action MemWrite(int client, int argc) {
	if (!client) {
		return Plugin_Handled;
	}
	
	int health = GetEntProp(client, Prop_Send, "m_iHealth");
	int healthOffs = FindSendPropInfo("CTFPlayer", "m_iHealth");
	
	Address pHealthOffs = view_as<Address>(view_as<int>(GetEntityAddress(client)) + healthOffs);
	
	Profiler prof = new Profiler();
	
	prof.Start();
	for (int i; i < NUM_ITERATIONS; i++) {
		SetEntData(client, healthOffs, health);
	}
	prof.Stop();
	ReplyToCommand(client, "SetEntData: %f", prof.Time);
	
	prof.Start();
	for (int i; i < NUM_ITERATIONS; i++) {
		StoreToAddress(pHealthOffs, health, NumberType_Int32);
	}
	prof.Stop();
	ReplyToCommand(client, "StoreToAddress(): %f", prof.Time);
	
	prof.Start();
	for (int i; i < NUM_ITERATIONS; i++) {
		StoreToAddress(pHealthOffs, health, NumberType_Int32, false);
	}
	prof.Stop();
	ReplyToCommand(client, "StoreToAddress(NoPageMod): %f", prof.Time);
	
	delete prof;
	
	return Plugin_Handled;
}

Micro benchmark results:

SetEntData: 0.044856
StoreToAddress(): 0.372449
StoreToAddress(NoPageMod): 0.009297

@Wend4r
Copy link
Contributor

Wend4r commented Jul 4, 2021

If speed is so important to you, then I suggest that you the write of a cell in memory without access changes in a separate native.

Also, I had the idea to make a additional methodmap Address, where there would be a Address.SetAccess() and etc.

@KyleSanderson KyleSanderson merged commit 387b854 into alliedmodders:master Jul 10, 2021
@KyleSanderson
Copy link
Member

The use-case is pretty terrible and is prone to corrupting state without extreme safety taken. However, writing memory should not be crazy more expensive than EntData which is ever so slightly more safe, so I've taken this in.

Please do not use this, or EntData, and use EntProp whenever possible when manipulating networked entity data.

@nosoop nosoop deleted the store-data-to-address branch July 11, 2021 06:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add StoreToAddress() alternative for data manipulation.
3 participants