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 // Initialize environment
system::init(); system::init();
system::initCpuFlags();
system::resetFpuFlags();
asset::init(); asset::init();
if (!settings::devMode) { if (!settings::devMode) {
logger::logPath = asset::user("log.txt"); 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); 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 } // 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); std::lock_guard<std::mutex> stepLock(internal->blockMutex);
SharedLock<SharedMutex> lock(internal->mutex); SharedLock<SharedMutex> lock(internal->mutex);
// Configure thread // Configure thread
system::initCpuFlags();
system::resetFpuFlags();
random::init(); random::init();


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


while (true) { while (true) {


+ 35
- 10
src/system.cpp View File

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


#include <system.hpp> #include <system.hpp>
#include <string.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 // Set CPU to flush-to-zero (FTZ) and denormals-are-zero (DAZ) mode
// https://software.intel.com/en-us/node/682949 // 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 // ARM64 always uses DAZ
#if defined ARCH_X64
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
// Round-to-nearest is default
#endif #endif


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


void init() {
initTime();
} }






Loading…
Cancel
Save