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 option to change SVE vector length for current and children processes #101295

Merged
merged 18 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/coreclr/vm/arm64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ LEAF_ENTRY GetDataCacheZeroIDReg, _TEXT
ret lr
LEAF_END GetDataCacheZeroIDReg, _TEXT

#if defined(_MSC_VER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed here and the same for the ifdef in the other file? I thought that asmhelpers.S was exclusively used by non-MSVC and asmhelpers.asm was exclusively used by MSVC (or rather MASM) and so there wasn't a need for such ifdefs (and why we don't have them elsewhere in these files)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I don't think _MSC_VER is needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know the call to this method is guarded under if (SVE), I am actually wondering the implications of calling it by someone without having this check? Is there a way to full proof this to return 0 or something if ran on non-sve arm64 machines?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, Arm64 doesn't have a user-mode way of checking CPU feature support

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So basically, if someone calls this method unintentionally, on non-sve arm64, they would just hit "Internal error", which is a fair thing to be.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh, I didn't know which one was used by MSVC and non-MSVC. In this case, we need to remove the non-MSVC bits from .S file because we need the "sve" attribute to compile it.

SwapnilGaikwad marked this conversation as resolved.
Show resolved Hide resolved
// DWORD64 __stdcall GetSveLengthFromOS(void);
jkotas marked this conversation as resolved.
Show resolved Hide resolved
LEAF_ENTRY GetSveLengthFromOS, _TEXT
rdvl x0, 1
ret lr
LEAF_END GetSveLengthFromOS, _TEXT
#endif // _MSC_VER

//-----------------------------------------------------------------------------
// This routine captures the machine state. It is used by helper method frame
//-----------------------------------------------------------------------------
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/vm/arm64/asmhelpers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@
ret lr
LEAF_END

#if defined(_MSC_VER)
;; DWORD64 __stdcall GetSveLengthFromOS(void);
jkotas marked this conversation as resolved.
Show resolved Hide resolved
LEAF_ENTRY GetSveLengthFromOS
rdvl x0, 1
SwapnilGaikwad marked this conversation as resolved.
Show resolved Hide resolved
ret lr
LEAF_END
#endif // _MSC_VER

SwapnilGaikwad marked this conversation as resolved.
Show resolved Hide resolved
;;-----------------------------------------------------------------------------
;; This routine captures the machine state. It is used by helper method frame
;;-----------------------------------------------------------------------------
Expand Down
15 changes: 11 additions & 4 deletions src/coreclr/vm/codeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1257,6 +1257,9 @@ void EEJitManager::SetCpuInfo()

int cpuFeatures = minipal_getcpufeatures();

// Get the maximum bitwidth of Vector<T>, rounding down to the nearest multiple of 128-bits
uint32_t maxVectorTBitWidth = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_MaxVectorTBitWidth) / 128) * 128;
SwapnilGaikwad marked this conversation as resolved.
Show resolved Hide resolved

#if defined(TARGET_X86) || defined(TARGET_AMD64)

#if defined(TARGET_X86) && !defined(TARGET_WINDOWS)
Expand All @@ -1271,9 +1274,6 @@ void EEJitManager::SetCpuInfo()

CPUCompileFlags.Set(InstructionSet_VectorT128);

// Get the maximum bitwidth of Vector<T>, rounding down to the nearest multiple of 128-bits
uint32_t maxVectorTBitWidth = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_MaxVectorTBitWidth) / 128) * 128;

if (((cpuFeatures & XArchIntrinsicConstants_VectorT256) != 0) && ((maxVectorTBitWidth == 0) || (maxVectorTBitWidth >= 256)))
{
// We allow 256-bit Vector<T> by default
Expand Down Expand Up @@ -1525,7 +1525,14 @@ void EEJitManager::SetCpuInfo()

if (((cpuFeatures & ARM64IntrinsicConstants_Sve) != 0) && CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_EnableArm64Sve))
{
CPUCompileFlags.Set(InstructionSet_Sve);
uint32_t maxVectorTLength = (maxVectorTBitWidth / 8);
uint64_t sveLengthFromOS = GetSveLengthFromOS();

// Do not enable SVE when the user specified vector length is smaller than the one offered by underlying OS.
if ((maxVectorTLength >= sveLengthFromOS) || (maxVectorTBitWidth == 0))
{
CPUCompileFlags.Set(InstructionSet_Sve);
}
}

// DCZID_EL0<4> (DZP) indicates whether use of DC ZVA instructions is permitted (0) or prohibited (1).
Expand Down
14 changes: 14 additions & 0 deletions src/coreclr/vm/codeman.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ Module Name:
#include "gcinfo.h"
#include "eexcp.h"

#if defined(TARGET_ARM64)
extern "C" DWORD64 __stdcall GetSveLengthFromOS();
jkotas marked this conversation as resolved.
Show resolved Hide resolved
#endif

class MethodDesc;
class ICorJitCompiler;
class IJitManager;
Expand Down Expand Up @@ -1912,6 +1916,16 @@ protected :
return m_CPUCompileFlags;
}

#if defined(TARGET_ARM64) && !defined(_MSC_VER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need of this anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need an "sve" attribute for GNUC builds. Not sure if #if defined(TARGET_ARM64) && defined(__GNUC__) is enough here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can only test on Arm64 host with Linux base systems at the moment so have to spam this CI for other build combinations.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need this definition because you will be using the one that is defined in asmhelpers.* files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay in responding. It doesn't compile after removing the definition of GetSveLengthFromOS from here.
The issue here is that on Linux, if we rely on asmhelpers.* files, we get compilation error error: instruction requires: sve or sme.
We avoid this error by adding the __attribute__((target("sve"))). However, this is attribute not defined for MSVC so we use asmhelpers.* files to define GetSveLengthFromOS there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does __attribute__((target("sve"))) traslate to in the .S file? I think you should be able to make the .S file compile by adding assembly equivalent of __attribute__((target("sve"))) to it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you looked into using .arch_extension sve in the .S file to get the SVE instruction to compile? It would look better if the .asm and .S files are symmetric.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SwapnilGaikwad - are you planning to try what @jkotas is suggesting?

__attribute__((target("sve")))
inline UINT64 GetSveLengthFromOS()
{
UINT64 size;
__asm__ __volatile__("rdvl %0, #1" : "=r"(size));
return size;
}
#endif // TARGET_ARM64

private:
bool m_storeRichDebugInfo;

Expand Down
Loading