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

[WASM][AOT] Generic methods are 5000x slower than non-generic methods using profiled AOT #48163

Closed
jeromelaban opened this issue Feb 11, 2021 · 7 comments
Labels
arch-wasm WebAssembly architecture area-Codegen-AOT-mono

Comments

@jeromelaban
Copy link
Contributor

jeromelaban commented Feb 11, 2021

Description

Repro: https://github.com/jeromelaban/Wasm.Samples/tree/master/Bug48163/Bug48163

Consider the following code:

	[MethodImpl(MethodImplOptions.NoInlining)]
	static int TestGeneric<T>(T value, int other)
	{
		for (int i = 0; i < innerCount; i++)
		{
			other += i;
		}

		return other;
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	static int TestNormal(int value, int other)
	{
		for (int i = 0; i < innerCount; i++)
		{
			other += i;
		}

		return other;
	}

The generic method is executing 5000x slower than the normal method (~5s vs. ~1ms), even when the profile recorded it.

When using Full AOT, this same generic method is running at the same speed than the normal method.

Additionally, with a similar benchmark, using Dictionary<,>:

  • 1M Dictionary<int,int>.TryGetValue() Mixed: 00:00:00.0385150, FullAOT: 00:00:00.0347
  • 1M Dictionary<string,string>.TryGetValue() Mixed: 00:00:00.04405, FullAOT: 00:00:00.0090600

Configuration

bb65067

Regression?

No.

Other information

@dotnet-issue-labeler dotnet-issue-labeler bot added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI untriaged New issue has not been triaged by the area owner labels Feb 11, 2021
jeromelaban added a commit to jeromelaban/Wasm.Samples that referenced this issue Feb 11, 2021
@CoffeeFlux CoffeeFlux added arch-wasm WebAssembly architecture area-Codegen-AOT-mono and removed area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI untriaged New issue has not been triaged by the area owner labels Feb 11, 2021
@ghost
Copy link

ghost commented Feb 11, 2021

Tagging subscribers to 'arch-wasm': @lewing
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Repro: https://github.com/jeromelaban/Wasm.Samples/tree/master/Bug48163/Bug48163

Consider the following code:

	[MethodImpl(MethodImplOptions.NoInlining)]
	static int TestGeneric<T>(T value, int other)
	{
		for (int i = 0; i < innerCount; i++)
		{
			other += i;
		}

		return other;
	}

	[MethodImpl(MethodImplOptions.NoInlining)]
	static int TestNormal(int value, int other)
	{
		for (int i = 0; i < innerCount; i++)
		{
			other += i;
		}

		return other;
	}

The generic method is executing 5000x slower than the normal method (~5s vs. ~1ms), even when the profile recorded it.

When using Full AOT, this same generic method is running at the same speed than the normal method.

Configuration

bb65067

Regression?

No.

Other information

Author: jeromelaban
Assignees: -
Labels:

arch-wasm, area-Codegen-AOT-mono

Milestone: -

@jeromelaban
Copy link
Contributor Author

The reason the generic method is not AOTed comes from this line:

GPtrArray *assemblies = mono_domain_get_assemblies (mono_get_root_domain ());

Where no assemblies are loaded during the profile parsing, making resolutions here fail:

if (!cdata->image->image)

@antonfirsov
Copy link
Member

antonfirsov commented Feb 22, 2021

I think this is critical to enable any computation-intensive library code to run with reasonable performance with profiled AOT.

For example people keep trying image processing with ImageSharp in the browser, I think it would be important to make that experience at least not terrible. ImageSharp relies heavily on generics, and I assume there are other libraries which also do so.

@jeromelaban
Copy link
Contributor Author

After investigating the issue a bit deeper, doing the following loads the assemblies and the profile gets loaded further:

if (acfg->aot_opts.image_files) {
	GList *l;
	MonoAssembly *assembly;
	printf("Loading additional image files\n");

	for (l = acfg->aot_opts.image_files; l; l = l->next) {
		printf("Loading additional assembly: %s\n", (char*)l->data);
		assembly = mono_domain_assembly_open_internal (mono_domain_get (), mono_domain_default_alc (mono_domain_get ()), (char*)l->data);

		if(!strcmp(ass->aname.name, assembly->aname.name)) {
			printf("Skip loading additional main assembly: %s\n", (char*)l->data);
			continue;
		}

		if(assembly){
			printf("Loaded additional assembly: %s\n", (char*)l->data);
			acfg->loaded_assemblies = g_slist_append (acfg->loaded_assemblies, assembly);
		}
		else{
			printf("Not loaded additional assembly: %s\n", (char*)l->data);
		}
	}
}
else {
	printf("No additional image files\n");
}

then changing resolve_profile_data to search in acfg->loaded_assemblies:

GSList *loaded_asm = acfg->loaded_assemblies;
printf ("acfg assemblies: %p\n", loaded_asm);
for (; loaded_asm; loaded_asm = loaded_asm->next) {
	MonoAssembly *ass = loaded_asm->data;

	if (!strcmp (ass->aname.name, idata->name)) {
		idata->image = ass->image;
		break;
	}
}

but even though loading the makes the resolution go further, deduping goes in the way and generic methods get excluded here:

@lewing
Copy link
Member

lewing commented Feb 25, 2021

Just for clarity, does this result apply with no profile?

@jeromelaban
Copy link
Contributor Author

Without a profile, the generic methods are AOTed properly, and the performance for both generic and non-generic method is similar.

@vargaz
Copy link
Contributor

vargaz commented Feb 27, 2021

This should be fixed now. The fix might cause issues to surface in other places.

@vargaz vargaz closed this as completed Feb 27, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Mar 29, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
arch-wasm WebAssembly architecture area-Codegen-AOT-mono
Projects
None yet
Development

No branches or pull requests

5 participants