Skip to content

Commit

Permalink
CPU Info Shenanigans
Browse files Browse the repository at this point in the history
1. Add the google C++ cpu detection protable code as a submod
2. Turn on AVX flags at build time
3. If you are running on a non-AVX box pop a warning saying may not
   work in the future
4. get popcorn

Closes surge-synthesizer#4466
  • Loading branch information
baconpaul committed May 3, 2021
1 parent abe00ca commit 1049ac2
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 62 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@
[submodule "libs/JUCE"]
path = libs/JUCE
url = https://github.com/juce-framework/JUCE
[submodule "libs/cpu_features"]
path = libs/cpu_features
url = https://github.com/google/cpu_features.git
21 changes: 20 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
add_compile_options(-msse2 -mfpmath=sse)
endif()
endif()

# Add AVX support
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#if defined(__x86_64__) || defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2)
#ifndef __AVX__
#error
#endif
#endif
int main() {}" COMPILER_HAS_AVX_OR_IS_ARM)
if (NOT COMPILER_HAS_AVX_OR_IS_ARM)
message(STATUS "Adding -mavx to allow __AVX__ compiles" )
add_compile_options("-mavx")
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Any Clang
add_compile_options(
Expand Down Expand Up @@ -76,7 +91,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU")
endif()

if(MSVC)
# MSVC and pretenders
add_compile_options(
-WX # treat all warnings as errors

Expand All @@ -97,6 +111,8 @@ if(MSVC)
/Zc:alignedNew
/bigobj

/arch:AVX

# Build with Multiple Processes (Clang-cl builds use Ninja instead)
$<$<CXX_COMPILER_ID:MSVC>:/MP>
)
Expand Down Expand Up @@ -138,6 +154,7 @@ add_subdirectory(libs/escape-from-vstgui)
add_subdirectory(libs/oddsound-mts)
add_subdirectory(libs/libsamplerate EXCLUDE_FROM_ALL)
add_subdirectory(libs/sqlite-3.23.3)
add_subdirectory(libs/cpu_features EXCLODE_FROM_ALL)

juce_add_binary_data(surge-shared-binary
NAMESPACE SurgeCoreBinary
Expand All @@ -159,6 +176,7 @@ target_link_libraries(surge-shared PUBLIC
surge::oddsound-mts
samplerate
surge-shared-binary
cpu_features
)

# We want to run this once alas, since JUCE needs it even though it is a byproduct of a phase to build the
Expand Down Expand Up @@ -274,6 +292,7 @@ set(SURGE_SHARED_SOURCES
src/common/vt_dsp/halfratefilter.cpp
src/common/vt_dsp/lipol.cpp
src/common/vt_dsp/macspecific.cpp
src/common/CPUFeatures.cpp
src/common/DebugHelpers.cpp
src/common/ModulatorPresetManager.cpp
src/common/Parameter.cpp
Expand Down
1 change: 1 addition & 0 deletions libs/cpu_features
Submodule cpu_features added at 3e8243
83 changes: 83 additions & 0 deletions src/common/CPUFeatures.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
** Surge Synthesizer is Free and Open Source Software
**
** Surge is made available under the Gnu General Public License, v3.0
** https://www.gnu.org/licenses/gpl-3.0.en.html
**
** Copyright 2004-2021 by various individuals as described by the Git transaction log
**
** All source at: https://github.com/surge-synthesizer/surge.git
**
** Surge was a commercial product from 2004-2018, with Copyright and ownership
** in that period held by Claes Johanson at Vember Audio. Claes made Surge
** open source in September 2018.
*/

#include "CPUFeatures.h"
#include "globals.h"

#if ARM_NEON
#else
#include "cpuinfo_x86.h"
#endif

using namespace cpu_features;

namespace Surge
{
namespace CPUFeatures
{
#if ARM_NEON
#else
static const X86Features features = GetX86Info().features;
#endif

std::string cpuBrand()
{
#if ARM_NEON
return "ARM Processor";
#else
char bs[49];
FillX86BrandString(bs);
return bs;
#endif
}

bool isArm()
{
#if ARM_NEON
return true;
#else
return false;
#endif
}
bool isX86()
{
#if ARM_NEON
return false;
#else
return true;
#endif
}
bool hasSSE2()
{
#if ARM_NEON
return true; // thanks simde
#else
return features.sse2;
#endif
}
bool hasAVX()
{
#if ARM_NEON
return true; // thanks simde
#else
return features.avx;
#endif
}

#if !CPU_FEATURES_COMPILED_X86_AVX
#error "You must compile SURGE with AVX support in compiler flags"
#endif
} // namespace CPUFeatures
} // namespace Surge
33 changes: 33 additions & 0 deletions src/common/CPUFeatures.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
** Surge Synthesizer is Free and Open Source Software
**
** Surge is made available under the Gnu General Public License, v3.0
** https://www.gnu.org/licenses/gpl-3.0.en.html
**
** Copyright 2004-2021 by various individuals as described by the Git transaction log
**
** All source at: https://github.com/surge-synthesizer/surge.git
**
** Surge was a commercial product from 2004-2018, with Copyright and ownership
** in that period held by Claes Johanson at Vember Audio. Claes made Surge
** open source in September 2018.
*/

#ifndef SURGE_XT_CPUFEATURES_H
#define SURGE_XT_CPUFEATURES_H

#include <string>

namespace Surge
{
namespace CPUFeatures
{
std::string cpuBrand();
bool isArm();
bool isX86();
bool hasSSE2();
bool hasAVX();
}; // namespace CPUFeatures
} // namespace Surge

#endif // SURGE_XT_CPUFEATURES_H
10 changes: 10 additions & 0 deletions src/common/SurgeSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "SurgeSynthesizer.h"
#include "DspUtilities.h"
#include <ctime>
#include "CPUFeatures.h"
#if MAC || LINUX
#include <pthread.h>
#else
Expand All @@ -38,6 +39,15 @@ SurgeSynthesizer::SurgeSynthesizer(PluginLayer *parent, std::string suppliedData
: storage(suppliedDataPath), hpA(&storage), hpB(&storage), _parent(parent), halfbandA(6, true),
halfbandB(6, true), halfbandIN(6, true)
{
// Remember CPU features works on ARM also
if (!Surge::CPUFeatures::hasAVX())
{
storage.reportError("Surge XT in the future will require processor with AVX extensions. Surge Xt may"
" not work on this hardware in future versions. Enjoy Surge 1.9!",
"CPU Incompatability");
// Try anyway
}

switch_toggled_queued = false;
audio_processing_active = false;
halt_engine = false;
Expand Down
63 changes: 2 additions & 61 deletions src/gui/CAboutBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "SurgeGUIEditor.h"
#include "CScalableBitmap.h"
#include "CTextButtonWithHover.h"
#include "CPUFeatures.h"

#if WINDOWS
// For __cpuid so we can get processor name
Expand Down Expand Up @@ -189,73 +190,13 @@ CAboutBox::CAboutBox(const CRect &size, SurgeGUIEditor *editor, SurgeStorage *st

std::string flavor = wrapperType;

std::string arch = std::string(Surge::Build::BuildArch);
std::string arch = Surge::CPUFeatures::cpuBrand();
#if MAC
std::string platform = "macOS";

char buffer[1024];
size_t bufsz = sizeof(buffer);
if (sysctlbyname("machdep.cpu.brand_string", (void *)(&buffer), &bufsz, nullptr, (size_t)0) < 0)
{
#if ARM_NEON
arch = "Apple Silicon";
#endif
}
else
{
arch = buffer;
#if ARM_NEON
arch += " (Apple Silicon)";
#endif
}

#elif WINDOWS
std::string platform = "Windows";

int CPUInfo[4] = {-1};
unsigned nExIds, i = 0;
char CPUBrandString[0x40];
// Get the information associated with each extended ID.
__cpuid(CPUInfo, 0x80000000);
nExIds = CPUInfo[0];
for (i = 0x80000000; i <= nExIds; ++i)
{
__cpuid(CPUInfo, i);
// Interpret CPU brand string
if (i == 0x80000002)
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000003)
memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo));
else if (i == 0x80000004)
memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo));
}
arch = CPUBrandString;
#elif LINUX
std::string platform = "Linux";

// Lets see what /proc/cpuinfo has to say for us
// on intels this is "model name"
auto pinfo = std::ifstream("/proc/cpuinfo");
if (pinfo.is_open())
{
std::string line;
while (std::getline(pinfo, line))
{
if (line.find("model name") == 0)
{
auto colon = line.find(":");
arch = line.substr(colon + 1);
break;
}
if (line.find("Model") == 0) // rasperry pi branch
{
auto colon = line.find(":");
arch = line.substr(colon + 1);
break;
}
}
}
pinfo.close();
#else
std::string platform = "GLaDOS, Orac or Skynet";
#endif
Expand Down

0 comments on commit 1049ac2

Please sign in to comment.