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 Environment.TotalProcessorCount or similar API, after semantics of Environment.ProcessorCount has changed #46283

Open
pgrawehr opened this issue Dec 21, 2020 · 4 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime
Milestone

Comments

@pgrawehr
Copy link

Background and Motivation

With #45943 the semantics of Environment.ProcessorCount is (for all systems) changed to the number of active processors the application can run on, taking the thread affinity mask into account. With this change, there's no more a direct possibility (without using OS-dependent PIvoke calls) to get the number of physical (or logical) CPUs in the system. This also prevents comparing the active vs the available CPU cores (i.e. to check whether an affinity mask has been applied).

Knowing the active physical processor count can be critical: I've come across a problem with a CPU in an embedded system that (due to a BIOS bug) would occassionally only start up with a single core. In that case, the system performance was to low for the application to run reliably and we had to tell the user of this situation.

Proposed API

Add

public int TotalProcessorCount
{
    get;
}

to System.Environment. An alternative would be the System.Diagnostics.Process class, which also supports setting the affinity. (Note: How would I know the valid affinity masks if I don't know the number of CPUs?)

Usage Examples

// Ensure our application runs on all available cores:
int numCores = Environment.TotalProcessorCount;
int affinityMask = (int)(Math.Pow(2, numCores) - 1);
System.Diagnostics.Process.ProcessorAffinity = affinityMask;

Alternative Designs

See above, the feature could be added to other classes. System.Diagnostics.Process or System.Diagnostics.ProcessThread would be an option. (Why is System.Diagnostics.ProcessThread.ProcessorAffinity write only, by the way?)

Risks

The whole system of affinity masks is a bit problematic when looking forward, as computers with more than 32 cores are likely to be widely available soon. So this might also require a larger redesign.

@pgrawehr pgrawehr added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Dec 21, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.Diagnostics.Process untriaged New issue has not been triaged by the area owner labels Dec 21, 2020
@ghost
Copy link

ghost commented Dec 21, 2020

Tagging subscribers to this area: @eiriktsarpalis
See info in area-owners.md if you want to be subscribed.

Issue Details

Background and Motivation

With #45943 the semantics of Environment.ProcessorCount is (for all systems) changed to the number of active processors the application can run on, taking the thread affinity mask into account. With this change, there's no more a direct possibility (without using OS-dependent PIvoke calls) to get the number of physical (or logical) CPUs in the system. This also prevents comparing the active vs the available CPU cores (i.e. to check whether an affinity mask has been applied).

Knowing the active physical processor count can be critical: I've come across a problem with a CPU in an embedded system that (due to a BIOS bug) would occassionally only start up with a single core. In that case, the system performance was to low for the application to run reliably and we had to tell the user of this situation.

Proposed API

Add

public int TotalProcessorCount
{
    get;
}

to System.Environment. An alternative would be the System.Diagnostics.Process class, which also supports setting the affinity. (Note: How would I know the valid affinity masks if I don't know the number of CPUs?)

Usage Examples

// Ensure our application runs on all available cores:
int numCores = Environment.TotalProcessorCount;
int affinityMask = (int)(Math.Pow(2, numCores) - 1);
System.Diagnostics.Process.ProcessorAffinity = affinityMask;

Alternative Designs

See above, the feature could be added to other classes. System.Diagnostics.Process or System.Diagnostics.ProcessThread would be an option. (Why is System.Diagnostics.ProcessThread.ProcessorAffinity write only, by the way?)

Risks

The whole system of affinity masks is a bit problematic when looking forward, as computers with more than 32 cores are likely to be widely available soon. So this might also require a larger redesign.

Author: pgrawehr
Assignees: -
Labels:

api-suggestion, area-System.Diagnostics.Process, untriaged

Milestone: -

@KalleOlaviNiemitalo
Copy link

(Why is System.Diagnostics.ProcessThread.ProcessorAffinity write only, by the way?)

Win32 has GetProcessAffinityMask and SetThreadAffinityMask but no GetThreadAffinityMask. No such information class in GetThreadInformation, either.

@pgrawehr
Copy link
Author

At least SetThreadAffinityMask can be abused to get the desired information: If the function succeeds, the return value is the thread's previous affinity mask.. While the limitations of the Win32 API may explain the current situation, the C# system APIs should, as far as possible, no longer be designed to match that API, but be based on the requirements of programmers. .NET is no longer Windows-only.

@pgrawehr
Copy link
Author

Related: #22948

@tannergooding tannergooding removed the untriaged New issue has not been triaged by the area owner label Jul 12, 2021
@tannergooding tannergooding added this to the Future milestone Jul 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Runtime
Projects
None yet
Development

No branches or pull requests

5 participants