Browse Source

Rename system::initCpuFlags() to system::resetFpuFlags(). Implement it on ARM64.

tags/v2.5.0
Andrew Belt 1 year ago
parent
commit
840e184d7e
4 changed files with 47 additions and 16 deletions
  1. +1
    -1
      adapters/standalone.cpp
  2. +9
    -3
      include/system.hpp
  3. +2
    -2
      src/engine/Engine.cpp
  4. +35
    -10
      src/system.cpp

+ 1
- 1
adapters/standalone.cpp View File

@@ -129,7 +129,7 @@ int main(int argc, char* argv[]) {

// Initialize environment
system::init();
system::initCpuFlags();
system::resetFpuFlags();
asset::init();
if (!settings::devMode) {
logger::logPath = asset::user("log.txt");


+ 9
- 3
include/system.hpp View File

@@ -195,10 +195,16 @@ The launched process will continue running if the current process is closed.
*/
void runProcessDetached(const std::string& path);

PRIVATE void init();
/** Sets Rack-recommended CPU flags for the current thread.
/** Returns the CPU's floating point unit control flags.
MXCSR register on x64, and the FPCR register on ARM64.
*/
uint32_t getFpuFlags();
void setFpuFlags(uint32_t flags);
/** Sets Rack-recommended FPU flags for the current thread.
*/
void initCpuFlags();
void resetFpuFlags();

PRIVATE void init();


} // namespace system


+ 2
- 2
src/engine/Engine.cpp View File

@@ -476,7 +476,7 @@ void Engine::stepBlock(int frames) {
std::lock_guard<std::mutex> stepLock(internal->blockMutex);
SharedLock<SharedMutex> lock(internal->mutex);
// Configure thread
system::initCpuFlags();
system::resetFpuFlags();
random::init();

internal->blockFrame = internal->frame;
@@ -1267,7 +1267,7 @@ void EngineWorker::run() {
// Configure thread
contextSet(engine->internal->context);
system::setThreadName(string::f("Worker %d", id));
system::initCpuFlags();
system::resetFpuFlags();
random::init();

while (true) {


+ 35
- 10
src/system.cpp View File

@@ -39,7 +39,6 @@

#include <system.hpp>
#include <string.hpp>
#include <simd/common.hpp>


/*
@@ -952,23 +951,49 @@ void runProcessDetached(const std::string& path) {
}


void init() {
initTime();
uint32_t getFpuFlags() {
#if defined ARCH_X64
return _mm_getcsr();
#elif defined ARCH_ARM64
uint64_t fpcr;
__asm__ volatile("mrs %0, fpcr" : "=r" (fpcr));
return fpcr;
#endif
}

void setFpuFlags(uint32_t flags) {
#if defined ARCH_X64
_mm_setcsr(flags);
#elif defined ARCH_ARM64
uint64_t fpcr = flags;
__asm__ volatile("msr fpcr, %0" :: "r" (fpcr));
#endif
}

void resetFpuFlags() {
uint32_t flags = 0;

void initCpuFlags() {
#if defined ARCH_X64
// Set CPU to flush-to-zero (FTZ) and denormals-are-zero (DAZ) mode
// https://software.intel.com/en-us/node/682949
// On ARM64, this is a SIMDe function.
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
// _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
flags |= 0x8000;
// _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
flags |= 0x0040;
// Round-to-nearest is default
#elif defined ARCH_ARM64
// Set Flush-to-Zero
flags |= 1 << 24;
// ARM64 always uses DAZ
#if defined ARCH_X64
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
// Round-to-nearest is default
#endif

// Reset rounding mode to default (nearest)
std::fesetround(FE_TONEAREST);
setFpuFlags(flags);
}


void init() {
initTime();
}




Loading…
Cancel
Save