ggml : use atomic_flag for critical section (#7598)

* ggml : use atomic_flag for critical section

* add windows shims
This commit is contained in:
slaren 2024-05-29 13:36:39 +02:00 committed by GitHub
parent 00281b7be3
commit 87bdf2a199
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

23
ggml.c
View File

@ -60,6 +60,9 @@
typedef volatile LONG atomic_int; typedef volatile LONG atomic_int;
typedef atomic_int atomic_bool; typedef atomic_int atomic_bool;
typedef atomic_int atomic_flag;
#define ATOMIC_FLAG_INIT 0
static void atomic_store(atomic_int * ptr, LONG val) { static void atomic_store(atomic_int * ptr, LONG val) {
InterlockedExchange(ptr, val); InterlockedExchange(ptr, val);
@ -73,6 +76,12 @@ static LONG atomic_fetch_add(atomic_int * ptr, LONG inc) {
static LONG atomic_fetch_sub(atomic_int * ptr, LONG dec) { static LONG atomic_fetch_sub(atomic_int * ptr, LONG dec) {
return atomic_fetch_add(ptr, -(dec)); return atomic_fetch_add(ptr, -(dec));
} }
static atomic_bool atomic_flag_test_and_set(atomic_flag * ptr) {
return InterlockedExchange(ptr, 1);
}
static void atomic_flag_clear(atomic_flag * ptr) {
InterlockedExchange(ptr, 0);
}
typedef HANDLE pthread_t; typedef HANDLE pthread_t;
@ -2883,24 +2892,20 @@ struct ggml_state {
// global state // global state
static struct ggml_state g_state; static struct ggml_state g_state;
static atomic_int g_state_barrier = 0; static atomic_flag g_state_critical = ATOMIC_FLAG_INIT;
// barrier via spin lock // barrier via spin lock
inline static void ggml_critical_section_start(void) { inline static void ggml_critical_section_start(void) {
int processing = atomic_fetch_add(&g_state_barrier, 1); while (atomic_flag_test_and_set(&g_state_critical)) {
// spin
while (processing > 0) { sched_yield();
// wait for other threads to finish
atomic_fetch_sub(&g_state_barrier, 1);
sched_yield(); // TODO: reconsider this
processing = atomic_fetch_add(&g_state_barrier, 1);
} }
} }
// TODO: make this somehow automatically executed // TODO: make this somehow automatically executed
// some sort of "sentry" mechanism // some sort of "sentry" mechanism
inline static void ggml_critical_section_end(void) { inline static void ggml_critical_section_end(void) {
atomic_fetch_sub(&g_state_barrier, 1); atomic_flag_clear(&g_state_critical);
} }
#if defined(__gnu_linux__) #if defined(__gnu_linux__)