-
Notifications
You must be signed in to change notification settings - Fork 11
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
SWAR Demos on ARM #70
Conversation
This is an excellent solution to discriminate away non portable things. |
@thecppzoo does this look good to you now? |
inc/zoo/pp/platform.h
Outdated
#define ZOO_CONFIGURED_TO_USE_AVX defined(__AVX2__) // TODO bring this in from CMake | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you choose to postpone the question of whether AVX2 is defined to every use of the macro instead of the more natural
#ifdef AVX/ #define ZOO_CONFIGURED/ #endif
?
I think I prefer that the conditional preprocessing at the point of use of ZOO_CONFIGURED... macros do not rely on any platform macro. But I have not thought long about the question, hence I ask you why you made the choice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you'd prefer to see:
#ifdef __AVX2__
#define ZOO_CONFIGURED_TO_USE_AVX2
#endif
As opposed to the above? I think the effects of either will be more or less equivalent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your question: yes.
The effects are not the same, see my question (which you did not answer explicitly), in my preferred conditional preprocessing the macro __AVX2__
is never used again after preprocessing platform.h. In the code you wrote, every use of the ZOO...
macro will query the definition of __AVX2__
, you've "postponed" the condition to every use. My question was whether you have a reason to prefer this behavior, especially since this is not the natural behavior.
It is slightly safer, and therefore better, to do this:
#ifdef __AVX2__
#define ZOO_CONFIGURED_TO_USE_AVX() 1
#else
#define ZOO_CONFIGURED_TO_USE_AVX() 0
Another minor thing, in 2024 I am not going to bother with the nuance of AVX versus AVX2, whenever the code talks of AVX or I refer to AVX, mentally you should understand I mean both; in exactly the same way we say SSE to refer to all of the SSEs, to mean x86-64 128 bit SIMD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the way, the zoo repository does not use #pragma once
because I frequently override headers. Imagine I'm doing some experiment in the Compiler Explorer and want to quickly enable or disable AVX:
I could override the platform header via:
#define ZOO_PLATFORM_MACROS_H
, then do what I would want with each platform macro.
Your formulation will transform ZOO_CONFIGURED_TO_USE_AVX
to the other macro I can't control in practice, the one provided by the system of __AVX2__
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, yes that makes total sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to add the brackets to make the macro look like a function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a very slight preference: it forces the macro to be defined. Imagine you rely on #ifdef
for your conditional compilation; you may inadvertently have compilation options that inconsistently define or not a particular macro, and it will apparently build (but inconsistently), which is frightening. If you use a function style macro, not only it needs to be defined, but expand to a preprocessing-time true or false; so, you can use the function-style macro everywhere consistently and catch inconsistencies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense to me... however I can't find other examples in zoo where this happens. Would you please idiot check me on these changes?
diff --git a/benchmark/atoi-corpus.h b/benchmark/atoi-corpus.h
index 783b6b1..525b761 100644
--- a/benchmark/atoi-corpus.h
+++ b/benchmark/atoi-corpus.h
@@ -120,7 +120,7 @@ struct CorpusStringLength {
};
-#if ZOO_CONFIGURED_TO_USE_AVX
+#if ZOO_CONFIGURED_TO_USE_AVX()
#define AVX2_STRLEN_CORPUS_X_LIST \
X(ZOO_AVX, zoo::avx2_strlen)
#else
diff --git a/benchmark/catch2swar-demo.cpp b/benchmark/catch2swar-demo.cpp
index 316163f..7e2e17a 100644
--- a/benchmark/catch2swar-demo.cpp
+++ b/benchmark/catch2swar-demo.cpp
@@ -36,7 +36,7 @@ TEST_CASE("Atoi benchmarks", "[atoi][swar]") {
REQUIRE(fromLIBC_STRLEN == fromZOO_NATURAL_STRLEN);
REQUIRE(fromZOO_NATURAL_STRLEN == fromZOO_MANUAL_STRLEN);
REQUIRE(fromGENERIC_GLIBC_STRLEN == fromZOO_NATURAL_STRLEN);
-#if ZOO_CONFIGURED_TO_USE_AVX
+#if ZOO_CONFIGURED_TO_USE_AVX()
REQUIRE(fromZOO_AVX == fromZOO_STRLEN);
#endif
diff --git a/inc/zoo/pp/platform.h b/inc/zoo/pp/platform.h
index b219226..c068259 100644
--- a/inc/zoo/pp/platform.h
+++ b/inc/zoo/pp/platform.h
@@ -2,9 +2,9 @@
#define ZOO_PLATFORM_MACROS_H
#ifdef __AVX2__
-#define ZOO_CONFIGURED_TO_USE_AVX 1
+#define ZOO_CONFIGURED_TO_USE_AVX() 1
#else
-#define ZOO_CONFIGURED_TO_USE_AVX 0
+#define ZOO_CONFIGURED_TO_USE_AVX() 0
#endif
#ifdef _MSC_VER
Results these errors.
In file included from /Users/jamiepond/projects/zoo/benchmark/catch2swar-demo.cpp:2:
/Users/jamiepond/projects/zoo/benchmark/atoi-corpus.h:123:5: error: function-like macro 'ZOO_CONFIGURED_TO_USE_AVX' is not defined
#if ZOO_CONFIGURED_TO_USE_AVX()
^
/Users/jamiepond/projects/zoo/benchmark/catch2swar-demo.cpp:39:5: error: function-like macro 'ZOO_CONFIGURED_TO_USE_AVX' is not defined
#if ZOO_CONFIGURED_TO_USE_AVX()
^
2 errors generated.
make[2]: *** [CMakeFiles/catch2Benchmark.dir/catch2swar-demo.cpp.o] Error 1
make[1]: *** [CMakeFiles/catch2Benchmark.dir/all] Error 2
make: *** [all] Error 2
jamiepond@jamies-mac build % make | pbcopy
In file included from /Users/jamiepond/projects/zoo/benchmark/catch2swar-demo.cpp:2:
/Users/jamiepond/projects/zoo/benchmark/atoi-corpus.h:123:5: error: function-like macro 'ZOO_CONFIGURED_TO_USE_AVX' is not defined
#if ZOO_CONFIGURED_TO_USE_AVX()
^
/Users/jamiepond/projects/zoo/benchmark/catch2swar-demo.cpp:39:5: error: function-like macro 'ZOO_CONFIGURED_TO_USE_AVX' is not defined
#if ZOO_CONFIGURED_TO_USE_AVX()
^
2 errors generated.
make[2]: *** [CMakeFiles/catch2Benchmark.dir/catch2swar-demo.cpp.o] Error 1
make[1]: *** [CMakeFiles/catch2Benchmark.dir/all] Error 2
make: *** [all] Error 2
If you could point us to other places zoo uses function-like macros to define a constant I would be grateful! Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be the first use of function-like macros in this branch of the repository, inside Snap we introduced several.
I did not see where you #include the platform header.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, I assumed it was already included higher up since it ostensibly was already working. This already shows the value of the brackets! Thanks for this!!
benchmark/atoi-corpus.h
Outdated
#include <vector> | ||
#include <string> | ||
#include <cstring> | ||
#include <random> | ||
#include <zoo/pp/platform.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Micro-nit:
In this codebase, please always #include from the most specific to the more general, like this:
- Headers specific to the feature related to the current file
- General zoo headers (
platform.h
should probably be the last) - Specific external librareis
- The standard library.
In this way, you give the chance to the local code to provide overrides for more general code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that makes sense !
Co-authored-by: thecppzoo <thecppzoo@gmail.com>
#define AVX2_STRLEN_CORPUS_X_LIST \ | ||
X(ZOO_AVX, zoo::avx2_strlen) | ||
#else | ||
#define AVX2_STRLEN_CORPUS_X_LIST /* nothing */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am going to immediately add cases to this X list, you'll see this was the proper way to encapsulate this.
Do you have "bandwidth" to help me do the equivalent for ARM? basically I can give you a diff patch that enables ARM, and hopefully it'll work, but if it doesn't you could fix it, of course that I will be online to help if you want
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup, i can add a patch if that helps. also feel free to push to this branch and i can pull and check it and fix errors i face
ifdef some stuff to get the benchmarks running on my ARM Mac.