diff --git a/benchmark/kostya/ondemand.h b/benchmark/kostya/ondemand.h index b0fce18d..369ffedb 100644 --- a/benchmark/kostya/ondemand.h +++ b/benchmark/kostya/ondemand.h @@ -12,7 +12,6 @@ using namespace simdjson::builtin; class OnDemand { public: simdjson_really_inline bool Run(const padded_string &json); - simdjson_really_inline const std::vector &Result() { return container; } simdjson_really_inline size_t ItemCount() { return container.size(); } @@ -43,7 +42,6 @@ namespace sum { class OnDemand { public: simdjson_really_inline bool Run(const padded_string &json); - simdjson_really_inline my_point &Result() { return sum; } simdjson_really_inline size_t ItemCount() { return count; } diff --git a/benchmark/largerandom/ondemand.h b/benchmark/largerandom/ondemand.h index 5516071f..42c4a9b9 100644 --- a/benchmark/largerandom/ondemand.h +++ b/benchmark/largerandom/ondemand.h @@ -12,7 +12,6 @@ using namespace simdjson::builtin; class OnDemand { public: simdjson_really_inline bool Run(const padded_string &json); - simdjson_really_inline const std::vector &Result() { return container; } simdjson_really_inline size_t ItemCount() { return container.size(); } @@ -40,7 +39,6 @@ namespace sum { class OnDemand { public: simdjson_really_inline bool Run(const padded_string &json); - simdjson_really_inline my_point &Result() { return sum; } simdjson_really_inline size_t ItemCount() { return count; } diff --git a/benchmark/partial_tweets/ondemand.h b/benchmark/partial_tweets/ondemand.h index 8003c42c..776bb4f0 100644 --- a/benchmark/partial_tweets/ondemand.h +++ b/benchmark/partial_tweets/ondemand.h @@ -9,10 +9,16 @@ namespace partial_tweets { using namespace simdjson; using namespace simdjson::builtin; + class OnDemand { public: + OnDemand() { + if(!displayed_implementation) { + std::cout << "On Demand implementation: " << builtin_implementation()->name() << std::endl; + displayed_implementation = true; + } + } simdjson_really_inline bool Run(const padded_string &json); - simdjson_really_inline const std::vector &Result() { return tweets; } simdjson_really_inline size_t ItemCount() { return tweets.size(); } @@ -30,6 +36,7 @@ private: ondemand::object u = std::move(user); return { u["id"], u["screen_name"] }; } + static inline bool displayed_implementation = false; }; simdjson_really_inline bool OnDemand::Run(const padded_string &json) { diff --git a/dependencies/cxxopts b/dependencies/cxxopts index 12e496da..794c9752 160000 --- a/dependencies/cxxopts +++ b/dependencies/cxxopts @@ -1 +1 @@ -Subproject commit 12e496da3d486b87fa9df43edea65232ed852510 +Subproject commit 794c975287355de48158d9a80ed502d26b20a472 diff --git a/doc/ondemand.md b/doc/ondemand.md index 001b2d16..d5a678ea 100644 --- a/doc/ondemand.md +++ b/doc/ondemand.md @@ -509,3 +509,21 @@ Good applications for the On Demand API might be: * You have a closed system on predetermined hardware. Both the generation and the consumption of JSON data is within your system. Your team controls both the software that produces the JSON and the software the parses it, your team knows and control the hardware. Thus you can fully test your system. * You are working with stable JSON APIs which have a consistent layout and JSON dialect. +## Checking Your CPU Selection + +Given that the On Demand API does not offer runtime dispatching, your code is compiled against a specific CPU target. You should +verify that the code is compiled against the target you expect: `haswell` (AVX2 x64 processors), `westmere` (SSE4 x64 processors), `arm64` (64-bit ARM), `fallback` (others). Under x64 processors, many programmers will want to target `haswell` whereas under ARM, +most programmers will want to target `arm64`. The `fallback` is probably only good for testing purposes, not for deployment. + +```C++ + std::cout << simdjson::builtin_implementation()->name() << std::endl; +``` + +If you are using CMake for your C++ project, then you can pass compilation flags to your compiler during the first configuration +by using the `CXXFLAGS` configuration variable: +``` +CXXFLAGS=-march=haswell cmake -B build_haswell +cmake --build build_haswell +``` + +You may also use the `CMAKE_CXX_FLAGS` variable. \ No newline at end of file diff --git a/include/simdjson/builtin.h b/include/simdjson/builtin.h index 7611458c..3420211f 100644 --- a/include/simdjson/builtin.h +++ b/include/simdjson/builtin.h @@ -29,6 +29,13 @@ namespace simdjson { * code that uses it) will use westmere. */ namespace builtin = SIMDJSON_BUILTIN_IMPLEMENTATION; + /** + * Function which returns a pointer to an implementation matching the "builtin" implementation. + * The builtin implementation is the best statically linked simdjson implementation that can be used by the compiling + * program. If you compile with g++ -march=haswell, this will return the haswell implementation. + * It is handy to be able to check what builtin was used: builtin_implementation()->name(). + */ + const implementation * builtin_implementation(); } // namespace simdjson #endif // SIMDJSON_BUILTIN_H diff --git a/src/implementation.cpp b/src/implementation.cpp index 021674bb..d9480e72 100644 --- a/src/implementation.cpp +++ b/src/implementation.cpp @@ -147,5 +147,10 @@ simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) noexcept { return active_implementation->validate_utf8(buf, len); } +const implementation * builtin_implementation() { + static const implementation * builtin_impl = available_implementations[STRINGIFY(SIMDJSON_BUILTIN_IMPLEMENTATION)]; + return builtin_impl; +} + } // namespace simdjson diff --git a/tests/ondemand/ondemand_basictests.cpp b/tests/ondemand/ondemand_basictests.cpp index 0d3fe667..07fb7274 100644 --- a/tests/ondemand/ondemand_basictests.cpp +++ b/tests/ondemand/ondemand_basictests.cpp @@ -1337,8 +1337,11 @@ int main(int argc, char *argv[]) { printf("unsupported CPU\n"); } // We want to know what we are testing. - std::cout << "Running tests against this implementation: " << simdjson::active_implementation->name(); - std::cout << "(" << simdjson::active_implementation->description() << ")" << std::endl; + // Next line would be the runtime dispatched implementation but that's not necessarily what gets tested. + // std::cout << "Running tests against this implementation: " << simdjson::active_implementation->name(); + // Rather, we want to display builtin_implementation()->name(). + // In practice, by default, we often end up testing against fallback. + std::cout << "builtin_implementation -- " << builtin_implementation()->name() << std::endl; std::cout << "------------------------------------------------------------" << std::endl; std::cout << "Running basic tests." << std::endl;