Skip to content

Commit 8e532fe

Browse files
committed
Add MSVC build support on windows
1 parent 6a7a01d commit 8e532fe

File tree

5 files changed

+82
-23
lines changed

5 files changed

+82
-23
lines changed

lib/meson.build

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ if cpp.has_argument('-march=haswell')
66
'x86simdsort-avx2.cpp',
77
),
88
include_directories : [src],
9-
cpp_args : ['-march=haswell'],
9+
cpp_args : meson.get_compiler('cpp').get_id() == 'msvc' ? ['/arch:AVX2'] : ['-march=haswell'],
1010
gnu_symbol_visibility : 'inlineshidden',
1111
dependencies: [omp_dep],
1212
)
@@ -18,7 +18,7 @@ if cpp.has_argument('-march=skylake-avx512')
1818
'x86simdsort-skx.cpp',
1919
),
2020
include_directories : [src],
21-
cpp_args : ['-march=skylake-avx512'],
21+
cpp_args : meson.get_compiler('cpp').get_id() == 'msvc' ? ['/arch:AVX512'] : ['-march=skylake-avx512'],
2222
gnu_symbol_visibility : 'inlineshidden',
2323
dependencies: [omp_dep],
2424
)
@@ -30,7 +30,7 @@ if cpp.has_argument('-march=icelake-client')
3030
'x86simdsort-icl.cpp',
3131
),
3232
include_directories : [src],
33-
cpp_args : ['-march=icelake-client'],
33+
cpp_args : meson.get_compiler('cpp').get_id() == 'msvc' ? ['/arch:AVX512'] : ['-march=icelake-client'],
3434
gnu_symbol_visibility : 'inlineshidden',
3535
dependencies: [omp_dep],
3636
)
@@ -42,7 +42,7 @@ if cancompilefp16
4242
'x86simdsort-spr.cpp',
4343
),
4444
include_directories : [src],
45-
cpp_args : ['-march=sapphirerapids'],
45+
cpp_args : meson.get_compiler('cpp').get_id() == 'msvc' ? ['/arch:AVX512'] : ['-march=sapphirerapids'],
4646
gnu_symbol_visibility : 'inlineshidden',
4747
dependencies: [omp_dep],
4848
)

lib/x86simdsort.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
#if defined(_MSC_VER)
2+
#define XSS_ATTRIBUTE_CONSTRUCTOR
3+
#else
4+
#define XSS_ATTRIBUTE_CONSTRUCTOR __attribute__((constructor))
5+
#endif
16
#include "x86simdsort.h"
27
#include "x86simdsort-internal.h"
38
#include "x86simdsort-scalar.h"
9+
#include "x86simdsortcpuid.h"
410
#include <algorithm>
511
#include <iostream>
612
#include <string>
@@ -12,23 +18,19 @@ static int check_cpu_feature_support(std::string_view cpufeature)
1218
if ((cpufeature == "avx512_spr") && (!disable_avx512))
1319
#if defined(__FLT16_MAX__) && !defined(__INTEL_LLVM_COMPILER) \
1420
&& (!defined(__clang_major__) || __clang_major__ >= 18)
15-
return __builtin_cpu_supports("avx512f")
16-
&& __builtin_cpu_supports("avx512fp16")
17-
&& __builtin_cpu_supports("avx512vbmi2");
21+
return xss_cpu_supports("avx512f") && xss_cpu_supports("avx512fp16")
22+
&& xss_cpu_supports("avx512vbmi2");
1823
#else
1924
return 0;
2025
#endif
2126
else if ((cpufeature == "avx512_icl") && (!disable_avx512))
22-
return __builtin_cpu_supports("avx512f")
23-
&& __builtin_cpu_supports("avx512vbmi2")
24-
&& __builtin_cpu_supports("avx512bw")
25-
&& __builtin_cpu_supports("avx512vl");
27+
return xss_cpu_supports("avx512f") && xss_cpu_supports("avx512vbmi2")
28+
&& xss_cpu_supports("avx512bw") && xss_cpu_supports("avx512vl");
2629
else if ((cpufeature == "avx512_skx") && (!disable_avx512))
27-
return __builtin_cpu_supports("avx512f")
28-
&& __builtin_cpu_supports("avx512dq")
29-
&& __builtin_cpu_supports("avx512vl");
30+
return xss_cpu_supports("avx512f") && xss_cpu_supports("avx512dq")
31+
&& xss_cpu_supports("avx512vl");
3032
else if (cpufeature == "avx2")
31-
return __builtin_cpu_supports("avx2");
33+
return xss_cpu_supports("avx2");
3234

3335
return 0;
3436
}
@@ -121,11 +123,11 @@ constexpr bool IS_TYPE_FLOAT16()
121123

122124
/* runtime dispatch mechanism */
123125
#define DISPATCH(func, TYPE, ISA) \
124-
DECLARE_INTERNAL_##func(TYPE) static __attribute__((constructor)) void \
125-
CAT(CAT(resolve_, func), TYPE)(void) \
126+
DECLARE_INTERNAL_##func(TYPE) static XSS_ATTRIBUTE_CONSTRUCTOR void CAT( \
127+
CAT(resolve_, func), TYPE)(void) \
126128
{ \
127129
CAT(CAT(internal_, func), TYPE) = &xss::scalar::func<TYPE>; \
128-
__builtin_cpu_init(); \
130+
xss_cpu_init(); \
129131
std::string_view preferred_cpu = find_preferred_cpu(ISA); \
130132
if constexpr (dispatch_requested("avx512", ISA)) { \
131133
if (preferred_cpu.find("avx512") != std::string_view::npos) { \
@@ -248,12 +250,12 @@ DISPATCH_ALL(argselect,
248250
}
249251

250252
#define DISPATCH_KV_FUNC(func, TYPE1, TYPE2, ISA) \
251-
static __attribute__((constructor)) void CAT( \
253+
static XSS_ATTRIBUTE_CONSTRUCTOR void CAT( \
252254
CAT(CAT(CAT(resolve_, func), _), TYPE1), TYPE2)(void) \
253255
{ \
254256
CAT(CAT(CAT(CAT(internal_, func), _), TYPE1), TYPE2) \
255257
= &xss::scalar::func<TYPE1, TYPE2>; \
256-
__builtin_cpu_init(); \
258+
xss_cpu_init(); \
257259
std::string_view preferred_cpu = find_preferred_cpu(ISA); \
258260
if constexpr (dispatch_requested("avx512", ISA)) { \
259261
if (preferred_cpu.find("avx512") != std::string_view::npos) { \

lib/x86simdsort.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
#include <functional>
77
#include <numeric>
88

9+
#if defined(_MSC_VER)
10+
#define XSS_EXPORT_SYMBOL __declspec(dllexport)
11+
#define XSS_HIDE_SYMBOL
12+
#else
913
#define XSS_EXPORT_SYMBOL __attribute__((visibility("default")))
1014
#define XSS_HIDE_SYMBOL __attribute__((visibility("hidden")))
15+
#endif
1116
#define UNUSED(x) (void)(x)
1217

1318
namespace x86simdsort {
@@ -73,11 +78,14 @@ XSS_EXPORT_SYMBOL void keyvalue_partial_sort(T1 *key,
7378
template <typename T, typename U, typename Func>
7479
XSS_EXPORT_SYMBOL void object_qsort(T *arr, U arrsize, Func key_func)
7580
{
76-
static_assert(std::is_integral<U>::value, "arrsize must be an integral type");
81+
static_assert(std::is_integral<U>::value,
82+
"arrsize must be an integral type");
7783
static_assert(sizeof(U) == sizeof(int32_t) || sizeof(U) == sizeof(int64_t),
7884
"arrsize must be 32 or 64 bits");
79-
using return_type_of = typename decltype(std::function{key_func})::result_type;
80-
static_assert(sizeof(return_type_of) == sizeof(int32_t) || sizeof(return_type_of) == sizeof(int64_t),
85+
using return_type_of =
86+
typename decltype(std::function {key_func})::result_type;
87+
static_assert(sizeof(return_type_of) == sizeof(int32_t)
88+
|| sizeof(return_type_of) == sizeof(int64_t),
8189
"key_func return type must be 32 or 64 bits");
8290
std::vector<return_type_of> keys(arrsize);
8391
for (U ii = 0; ii < arrsize; ++ii) {

lib/x86simdsortcpuid.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#ifndef X86SIMDSORT_CPUID_H
2+
#define X86SIMDSORT_CPUID_H
3+
4+
#ifdef _MSC_VER
5+
#include <intrin.h>
6+
#include <string>
7+
#include <unordered_map>
8+
9+
static std::unordered_map<std::string, bool> xss_cpu_features;
10+
11+
inline void xss_cpu_init()
12+
{
13+
int cpuInfo[4] = {0};
14+
// Check AVX2
15+
__cpuid(cpuInfo, 0);
16+
int nIds = cpuInfo[0];
17+
__cpuid(cpuInfo, 1);
18+
bool osxsave = (cpuInfo[2] & (1 << 27)) != 0;
19+
bool avx = (cpuInfo[2] & (1 << 28)) != 0;
20+
__cpuid(cpuInfo, 7);
21+
bool avx2 = (cpuInfo[1] & (1 << 5)) != 0;
22+
bool avx512f = (cpuInfo[1] & (1 << 16)) != 0;
23+
bool avx512dq = (cpuInfo[1] & (1 << 17)) != 0;
24+
bool avx512bw = (cpuInfo[1] & (1 << 30)) != 0;
25+
bool avx512vl = (cpuInfo[1] & (1 << 31)) != 0;
26+
bool avx512vbmi2 = (cpuInfo[2] & (1 << 6)) != 0;
27+
bool avx512fp16 = (cpuInfo[3] & (1 << 23)) != 0;
28+
// Store results
29+
xss_cpu_features["avx2"] = avx2;
30+
xss_cpu_features["avx512f"] = avx512f;
31+
xss_cpu_features["avx512dq"] = avx512dq;
32+
xss_cpu_features["avx512bw"] = avx512bw;
33+
xss_cpu_features["avx512vl"] = avx512vl;
34+
xss_cpu_features["avx512vbmi2"] = avx512vbmi2;
35+
xss_cpu_features["avx512fp16"] = avx512fp16;
36+
}
37+
38+
inline bool xss_cpu_supports(const char *feature)
39+
{
40+
auto it = xss_cpu_features.find(feature);
41+
return it != xss_cpu_features.end() && it->second;
42+
}
43+
44+
#else
45+
#define xss_cpu_init() __builtin_cpu_init()
46+
#define xss_cpu_supports(feature) __builtin_cpu_supports(feature)
47+
#endif // _MSC_VER
48+
#endif // X86SIMDSORT_CPUID_H

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
project('x86-simd-sort', 'cpp',
23
version : '7.0.x',
34
license : 'BSD 3-clause',

0 commit comments

Comments
 (0)