Как стать автором
Обновить
27
0

Пользователь

Отправить сообщение
Вы достигли этого заменив английские слова на занки препинания, и таким образом заменили одну невозможность на другую, и я вам это уже выше объяснил.

Итого в остатке мы имеем просто замену слов известных большей части человечества, на непонятные знаки со смыслом не известным большей части человечаства только из соображения «избегания латино-иностранного микса».
Важно ведь не только то, что эти знаки есть в языке, но и для чего они используются. Например, в вашем SPL есть ?, а в Python есть if, но если они обозначают похожие вещи, то какая разница, какую строчку вы для этого будете использовать? Или вам принципиально претит именно использованалие английских слов для таких конструкций, но при этом знаки препинания для таких вещей это ок?
Так и я вам вроде вполне доходчиво объяснил, что не смотря на то, что вы не используете английский язык, вы используете другой язык, но это тоже язык и вы тоже не можете от него отойти в SPL.

Итого что мы имеем:
  • Python со своей невозможностью отойти от одного из самых широко распространенных в мире языков;
  • SPL с невозможностью отойти от одного из самых нероспрастраненных в мире языков.


В вашем языке можно создать микс из закорючек и любого другого языка, в Python можно создать микс из английского и любого другого языка. В чем принципиальная разница? Вы одну невозможность заменили другой и что дальше-то?
Невозможность чего я выдаю за норму?
  1. Python (и многие другие) тоже позволяет избежать микса — используйте только ланиницу и микса не будет;
  2. вы избегаете микса ценой замены слов известных довольно солидной части человечества на понятные только избранным закарючки.

«Особенность» — это очень хороше слово, чтобы описать данную ситуацию.
Очевидно, другом по сравнению с SPL. Например, у вас вместо ключевых слов странные закорючки вроде ?, но это тоже слово языка, непонятного, но тем не менее языка, не английского, но тем не менее языка. Заменить? на какую-нибудь другую произвольную закарючку не получится. Т. е. у вас «гараммтические конструкции» тоже не могут быть на «другом языке».
А где в моем комментарии вы видите что-то про латиницу?
Нет, не могут быть, они могут быть только на языке Python, но ведь у вас они тоже не могут быть на другом языке.
#!/usr/bin/env python3

напечатать = print
приветствие = 'Hello, World'
напечатать(приветствие)

Python 3.5.2, работает без видимых проблем, документация разрешает не только латинские буквы.

Т. е. повреждение магнитной головки диска это не достаточно тотально?


Журнал помогает от сбоев, вопрос в том от каких. Он помогает при отключения питания, но от повреждения данных на диске журнал не спасает.

Метафора описывает то, что происходит с компьютером или программой при сбое — данные на диске могут быть безнадежно искаженны. Более серьезные неудачи отшельника могут сравниться с такими событиями, как повреждение блока магнитных головок, которые могут нанести ущерб не только написанным словам, но и оставить довольно неприятную и постоянную отметку на всей странице.

Эти проблемы решены с помощью журналирования. Схема заключается в том, чтобы ничего не стирать, точно так же, как люди ведут журналы учёта или лабораторный дневник наблюдений. Теперь наш отшельник держит стопку бумаг, и, когда он хочет внести изменения в законы, он добавляет новую запись в свой журнал

Каким образом журналирование поможет вам побороться с повреждением данных на диске?
Так вот не надо тут, я посмотрел на два последних, стандартные блокирвки упоминаются в std::mutex & std::map и std::shared_mutex & std::map, но в легенде нет ни слова про то, что в них используется партицирование, отсюда и возник вопрос.

Более того у вас же в репозитории в каталоге banchmark есть бенчмарк и график, где std::map с партицированнием и стандартными мьютексами вы обозначили как safe_map_partitioned_t<>, а std::map & std::mutex обозначает, как я понял стандартную мапу защищенную одним мьютексом.

Я посмотрел ровно то, на что вы указали.
Такие задачи есть, но не все задачи такие, а память тратится всегда. Я это к тому, что при разработке стандартной библиотеки, которая используется довольно широко, задумываются не только о скорости, но и о памяти.

Поправьте меня, если я не правильно понял результаты, но в тестах там идет сравнения мапы с одним стандартным локом защищяющим доступ к ней, против варианта с партицированием и вашими локами? Если так, то честно говоря сравнение не очень честно, ведь партицированные очень сильно влияет. А в репозитории результатов бенчмарка для 60 ядер я не нешел (тольк для 16 потоков на 10 ядрах с HT) и там safe_map_partitioned_t с дефолтными локами не так уж и плох.
1. только придется таскать все эти инстанцирования за собой, хотя проблему с ABI это решит
2. в большинстве задач впринципе стоит стараться избегать ситуации, когда куча потоков постоянно деруться за одну блокировку — ваши тесты, из того что я увидел, оценивают ровно эту ситуацию.
1. эти локи существенно полагаются на compile time параметр:
— если его выбрать неправильно, то пострадает производительность
— при каждом изменении придется пересобирать код, а в случае библиотек это еще и ABI сломает
2. это 60 байт умножить на compile time константу и на количество блокировок
3. стандартные блокировки не так уж и плохи, просто не лучшее решение на все случаи жизни
Ну shared_mutex там только для примера, вместо него можно поставить все что угодно и интерфейс не будет особо важен в этом и суть вопроса. В том числе и обычную TAS/CAS/XCHG блокировку с произвольной стратегией ожидания, или Ticket Lock или MCS, которые должны неплохо справляться с неожиданныыми припадками, когда все вдруг ломятся хватать блокировку.
Spinlock далеко не всегда хуже, чем std::mutex, особенно если важно, чтобы не было слишком больших задержек.
Ну я не говорил, что он хуже, но то что он не всегда хуже не значит, что он всегда лучше. Да и более или менее разуменые реализации mutex-ов обычно таки оптимистично ожидают активно некоторое время, т. е. в случае отсутсвия конкуренции, они не должны быть супер плохи.

К тому же, читателям требуется операция проверки — установлена ли эксклюзивная блокировка без её захвата (чтобы не гонять x-state кэш-линии) — такой интерфейс не предоставляют ни std::mutex, ни std::shared_mutex, сюда не подходят ни lock(), ни try_lock().
Ну это только часть правды, они действительно такой интерфейс не предоставляют, но без него можно обойтись, как-нибудь так:
void lock_shared() {
	int const register_index = register_thread();

	if (register_index >= 0) {
		int recursion_depth = shared_locks_array[register_index].value.load(std::memory_order_acquire);
		assert(recursion_depth >= 1);

		if (recursion_depth > 1) {
			shared_locks_array[register_index].value.store(recursion_depth + 1, std::memory_order_release);
		else {
			shared_locks_array[register_index].value.store(recursion_depth + 1);
			while (writers.load()) {
				shared_locks_array[register_index].value.store(recursion_depth);
				for (size_t i = 0; writers.load(); ++i)
					if (i % 100000 == 0) std::this_thread::yield();
				shared_locks_array[register_index].value.store(recursion_depth + 1);
			}
		}
	}
	else {
		if (owner_thread_id.load(std::memory_order_acquire) != get_fast_this_thread_id())
			mtx.lock_shared();
		++recursive_xlock_count;
	}
}

void lock() {
	int const register_index = get_or_set_index();
	if (register_index >= 0)
		assert(shared_locks_array[register_index].value.load(std::memory_order_acquire) == 1);

	if (owner_thread_id.load(std::memory_order_acquire) != get_fast_this_thread_id()) {
		++writers;
		mtx.lock();
		owner_thread_id.store(get_fast_this_thread_id(), std::memory_order_release);

		for (auto &i : shared_locks_array)
			while (i.value.load() > 1);
	}
	++recursive_xlock_count;
}

Таким образом, если я ничего не напутал, даже неудачливые читатели не будут хватать блокировку в эксклюзивном виде.
Пара вопросов:

1. ваш лок содержит обычную TAS блокировку, которую хватают неудачливые читатели и писатели, но я не вижу причин, почему эта блокировка не вынесена в отдельную компоненту, я что-то пропустил или просто так?
2.1. есть ли у вас результаты тестирования в случае, если количество потоков больше чем константа-параметр класса блокировки? У меня в данный момент в наличии нет машины, чтобы самому померить, но интересует на сколько сильно неудачливые читатели будут мешать писателям и друг другу (тем более, что там просто активное ожидание)?
2.2. нет ли смысла, например, заменить TAS на какой-нибудь ticket rwlock, чтобы и неудачливым читателям дать какую-то свободу, или вообще для них просто откатиться к стандартному shared_mutex?
А если все операции такого цикла выполняются без пессимистических блокировок, то такой алгоритм называется lock-free.
Немного странное утверждение, алгоритм/структура данных является lock-free, если он/она предоставляет определенные гарантии прогресса, а не только, если в ней отсутствует использование блокировок. Таким образом, то что вы пишите не совсем согласуется с понятием lock-free:
1. заметим, что используя то, что вы назвали оптимистичной блокировкой (тот самый цикл с CAS операциями), можно реализовать то, что вы назвали пессимистичной блокировкой и использовать эту реализацию, таким образом, в алогоритме без явного использования блокировок блокировка может присутствовать неявно
2. то, что в алгоритме нет блокировок, не делает его автоматически lock-free, например, он может предоставлять более слабую гарантию obstruction-free.
Наверно, потому что pthread_create может вернуть ошибку?

Информация

В рейтинге
Не участвует
Откуда
Санкт-Петербург, Санкт-Петербург и область, Россия
Дата рождения
Зарегистрирован
Активность