LINUX.ORG.RU

Синхронизация потоков

 ,


0

1

Есть код такого вида:

#include <stdatomic.h>

struct { long l; char s[8]; } queue[1024 * 1024];
_Atomic int qsize;

void process_queue() {
  extern void process(typeof(*queue));
#ifdef X86
  for (int i; (i = atomic_fetch_sub_explicit(&qsize, 1, memory_order_acq_rel)) > 0; process(queue[i - 1]));
#else
  int i = atomic_fetch_sub_explicit(&qsize, 1, memory_order_acquire);
  while (i > 0) { process(queue[i - 1]); i = atomic_fetch_sub_explicit(&qsize, 1, memory_order_relaxed); }
  atomic_fetch_sub_explicit(&qsize, 1, memory_order_release);
#endif
}
void extra_thread() {
  while (1) { while (atomic_load_explicit(&qsize, memory_order_relaxed) <= 0); process_queue(); }
}
void main_thread() {
  while (1) {
    extern int thread_count;
    extern int get_data(typeof(queue), int);
    atomic_store_explicit(&qsize, get_data(queue, sizeof(queue) / sizeof(*queue)), memory_order_release);
    process_queue();
    while (atomic_load_explicit(&qsize, memory_order_relaxed) !=
#ifdef X86
      -thread_count + 1
#else
      -thread_count + 1 << 1
#endif
    );
  }
}

С х86 вопросов нет. Хоть как пиши - оно будет работать/тормозить одинаково. С чем-то другим не совсем понятно. Можно ли сделать лучше, чем мой вариант под #else?

В get_data сисколы и в реальности можно просто писать relaxed везде и всё будет работать. Но интересно как сделать «по правилам»(из стандарта).

Ответ на: комментарий от anonymous

Смотри ещё прикол

//c++
#include <iostream>
#include <format>

using namespace std;

int
main ()
{
  cout.sync_with_stdio (false);

  double s01 = 15.15;
  double s02 = 25.25;
  double s03 = 75.75;
  double s04 = 15.15;
  double s05 = 25.25;
  double s06 = 75.75;
  double s07 = 15.15;
  double s08 = 25.25;
  double s09 = 75.75;
  double s10 = 15.15;
  double s11 = 25.25;
  double s12 = 75.75;

  for (int i = 0; i < 10000000; ++i)
    {
      std::cout << std::format("{} {} {} {} {} {} {} {} {} {} {} {}",
            s01, s02, s03, s04, s05, s06, s07, s08, s09, s10, s11, s12);

    }
}

// c
#include <stdio.h>

int
main ()
{
  double s01 = 15.15;
  double s02 = 25.25;
  double s03 = 75.75;
  double s04 = 15.15;
  double s05 = 25.25;
  double s06 = 75.75;
  double s07 = 15.15;
  double s08 = 25.25;
  double s09 = 75.75;
  double s10 = 15.15;
  double s11 = 25.25;
  double s12 = 75.75;

  for (int i = 0; i < 10000000; ++i)
    {
      printf ("%f %f %f %f %f %f %f %f %f %f %f %f", s01, s02, s03, s04, s05,
              s06, s07, s08, s09, s10, s11, s12);
    }
}

$ time ./c > /dev/null real 0m39.221s

$ time ./cpp > /dev/null real 0m26.235s

anonymous
()
Ответ на: комментарий от anonymous

1. Должен быть код ошибки. Отформатировали строку в буффер, проверили флаг ошибки, если всё нормально - вывели. Если нужен непосредственный вывод несмотря на ошибки - указываем это отдельно.
2. Один раз построил формат, потом записал. Сколько надо раз. Конечно хотелось бы компилируемый формат как в {fmt}, но после того как видел код fmt - уже не хочется.
3. Не быстрее даже несмотря на это. {fmt} быстрее. Вообще нулль-терминированные строки сам по себе весьма неэффективная вещь и лучше всегда что-то вроде string_view использовать. Только вот современные c++ утилиты страшные до безобразия. Код того же {fmt} понятнее в декомпиле, чем в исходниках

mittorn ★★★★★
()
Последнее исправление: mittorn (всего исправлений: 1)
Ответ на: комментарий от anonymous

printf(std::format(…).c_str())

А чего время такого теста не прикрепил? Не удалось порвать тормозной цпп с евой виртуальностью и косвенными вызовами? Если ты не понял, повторю - в своих тестах ты пользовался тем, что в цпп совершается несколько вызовов operator<<, которые в условиях невозможности заинлайнить дают существенный лаг. А не потому что ты там рассказывал что iostream там тормозной из-за всего этого высокоуровнего говна.

Причем тут «iostream»?

Потому что я через него выводил std::format? Который прошел через вереницу косвенных вызовов/манипуляторов и прочих перделок. А главное - более-менее сравнялось количество вызовов

Знаете ли вы, что iostream быстрее сишного printf?

Да, такие кейсы я тебе показал, за слова свои ответил

«За сим откланяюсь» (ц)

anonymous
()