powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / вопрос по потокам
34 сообщений из 34, показаны все 2 страниц
вопрос по потокам
    #38326153
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Надо изменить массив, причём сделать изменения требуется вне зависимости от значений элементов массива (просто добавлять к определённым членам массива определённые извне значения, которые не зависят от массива). Надо ли использовать критические секции или что-то ещё или же при таких операциях в этом нет необходимости?
...
Рейтинг: 0 / 0
вопрос по потокам
    #38326487
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvango,

Это зависит от волнующих подробностей, которые ты не указал.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38326519
зависит от того, будут ли одновременно потоки обращаться к разным элементам массива, или же вполне могут к одним и тем же. Если первое, то можешь не синхронизировать потоки. Если второе, то зависит от волнующих подробностей, которые ты не указал ;) Например, если потоки могут одновременно писать в один элемент, то однозначно нужна та или иная синхронизация, если один пишет, а другие читают, то в зависимости от типа данных в массиве нужно (или не нужно) синхронизировать потоки.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38326673
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нужно знать масштабы задачи. Сколько будет потоков. Каков размер массива. (приблизительно).
Просто глупо вешать мутекс на каждый элемент массива (если это биткарта). Нужно как-то
мыслить количественными оценками.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38326764
ayvangoНадо изменить массив, причём сделать изменения требуется вне зависимости от значений элементов массива ( просто добавлять к определённым членам массива определённые извне значения, которые не зависят от массива). Надо ли использовать критические секции или что-то ещё или же при таких операциях в этом нет необходимости?
Что значит добавлять, арифметически складывать?

Для примера конкурентное добавление из разных потоков к элементу массива с индексом 10:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
#include<iostream>
#include<atomic>
#include<thread>
#include<array>
#include<vector>

std::array< std::atomic<int>, 1024*1024 > atomic_array;

int main() {
    for(auto &i : atomic_array) i.store(0, std::memory_order_relaxed);

	std::vector<std::thread> t_grp(std::thread::hardware_concurrency());
	for(auto &i : t_grp) i.swap(std::thread([](){
							for(size_t i = 0; i < 10000000; ++i)
								atomic_array[10].fetch_add(1, std::memory_order_relaxed);
						} ));
	for(auto &i : t_grp) i.join();

	std::cout << "std::thread::hardware_concurrency() = " << std::thread::hardware_concurrency() << std::endl;
	std::cout << "atomic_array[10] = " << atomic_array[10] << std::endl;

    int b;
	std::cin >> b;
    return 0;
}
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327142
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добавлять -- арифметически складывать.
Размер массива -- 100 М элементов. Тип элементов -- double.
Я так понял, стоит задуматься над тем, как разным потокам поставить во взаимнооднозначное соответствие разные элементы, чтобы только один поток изменял один элемент, тогда не требуется никакой синхронизации, верно?
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327144
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
число потоков -- 4-20.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327145
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvango, в точку.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327303
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
член массивазависит от того, будут ли одновременно потоки обращаться к разным элементам массива, или же вполне могут к одним и тем же. Если первое, то можешь не синхронизировать потоки. Если второе, то зависит от волнующих подробностей, которые ты не указал ;) Например, если потоки могут одновременно писать в один элемент, то однозначно нужна та или иная синхронизация, если один пишет, а другие читают, то в зависимости от типа данных в массиве нужно (или не нужно) синхронизировать потоки.


Зависит в первую очередь от того, что такое "массив", я бы сказал...
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327304
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
член массива...если один пишет, а другие читают, то в зависимости от типа данных в массиве нужно (или не нужно) синхронизировать потоки.


Ошибаешься, в таком случае также безусловно нужна синхронизация.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327305
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonНужно знать масштабы задачи. Сколько будет потоков. Каков размер массива. (приблизительно).
Просто глупо вешать мутекс на каждый элемент массива (если это биткарта). Нужно как-то
мыслить количественными оценками.

Зачем на каждый ? НА весь массив вешать надо.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327346
ayvangoДобавлять -- арифметически складывать.
Размер массива -- 100 М элементов. Тип элементов -- double.
Я так понял, стоит задуматься над тем, как разным потокам поставить во взаимнооднозначное соответствие разные элементы, чтобы только один поток изменял один элемент , тогда не требуется никакой синхронизации, верно?
Если это можно, то конечно нужно!
А ещё лучше в такой ситуации в каждом потоке иметь свой локальный массив.

Если же все равно иногда могут разные потоки обращаться к разным элементам массива, то по аналогии:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
#include<iostream>
#include<atomic>
#include<thread>
#include<array>
#include<vector>

std::array< std::atomic<double>, 1024*1024 > atomic_array;

int main() {
    for(auto &i : atomic_array) i.store(0, std::memory_order_relaxed);

	std::vector<std::thread> t_grp(std::thread::hardware_concurrency());
	for(auto &i : t_grp) i.swap(std::thread([](){
							for(size_t i = 0; i < 10000000; ++i)
								atomic_array[10].fetch_add(1, std::memory_order_relaxed);
						} ));
	for(auto &i : t_grp) i.join();

	std::cout << "std::thread::hardware_concurrency() = " << std::thread::hardware_concurrency() << std::endl;
	std::cout << "atomic_array[10] = " << atomic_array[10] << std::endl;

    int b;
	std::cin >> b;
    return 0;
}
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327347
конкурентное добавлениеЕсли же все равно иногда могут разные потоки обращаться к разным одним и тем же элементам массива
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327416
MasterZivчлен массива...если один пишет, а другие читают, то в зависимости от типа данных в массиве нужно (или не нужно) синхронизировать потоки.Ошибаешься, в таком случае также безусловно нужна синхронизация.Не ошибаюсь. Если элементы являются простыми типами (32-х битное, например), то один поток может менять что хочет и как хочет, при том что другие потоки могут читать эти изменяемые элементы без синхронизации. Если же тип данных сложен и для него не существует атомарной операции для записи изменения в память (тот же double на 32-х битных системах и при размере структуры 8 байт будет записываться в элемент массива за два приема - первые 32 бита, затем вторые), то тут да, читающие потоки могут словить "полуготовое" значение, не являющееся ни старым, ни новым значением элемента, тут обязательно нужно синхронизировать читателей с писателем.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327438
член массиваMasterZivпропущено...
Ошибаешься, в таком случае также безусловно нужна синхронизация.Не ошибаюсь. Если элементы являются простыми типами (32-х битное, например), то один поток может менять что хочет и как хочет, при том что другие потоки могут читать эти изменяемые элементы без синхронизации. Если же тип данных сложен и для него не существует атомарной операции для записи изменения в память (тот же double на 32-х битных системах и при размере структуры 8 байт будет записываться в элемент массива за два приема - первые 32 бита, затем вторые), то тут да, читающие потоки могут словить "полуготовое" значение, не являющееся ни старым, ни новым значением элемента, тут обязательно нужно синхронизировать читателей с писателем.
Помимо проблемы полуготовых данных, есть ещё проблема переупорядочивания компилятором, конвейером и кэшом - так что в зависимости от задачи могут понадобиться и барьеры памяти.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327506
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivmaytonНужно знать масштабы задачи. Сколько будет потоков. Каков размер массива. (приблизительно).
Просто глупо вешать мутекс на каждый элемент массива (если это биткарта). Нужно как-то
мыслить количественными оценками.

Зачем на каждый ? НА весь массив вешать надо.
А может разбить на блоки?
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327570
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
член массиваMasterZivпропущено...
Ошибаешься, в таком случае также безусловно нужна синхронизация.Не ошибаюсь. Если элементы являются простыми типами (32-х битное, например), то один поток может менять что хочет и как хочет, при том что другие потоки могут читать эти изменяемые элементы без синхронизации. Если же тип данных сложен и для него не существует атомарной операции для записи изменения в память (тот же double на 32-х битных системах и при размере структуры 8 байт будет записываться в элемент массива за два приема - первые 32 бита, затем вторые), то тут да, читающие потоки могут словить "полуготовое" значение, не являющееся ни старым, ни новым значением элемента, тут обязательно нужно синхронизировать читателей с писателем.

Это расхожее заблуждение.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327572
ayvango
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И ещё вопрос: Если я пишу

Thread[] t = new Thread[4];
for (int i = 0; i < 4; ++i)
{
t[i] = new Thread(() => { for (int j = i; j < N; j += core) temp += f(j); });
}

for (int i = 0; i < 4; ++i) t[i].Start();

, то выполняется дольше, чем если бы я создал отдельно 4 потока без использования массива t, после чего запустил бы их.

Почему это происходит и как этого избежать, если надо создавать много потоков?
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327579
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
MasterZivЭто расхожее заблуждение.На x86 - можно, в общем случае - нет. Ок?
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327647
MasterZivчлен массивапропущено...
Не ошибаюсь.
Это расхожее заблуждение.
Теоретик детектед
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327746
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
?MasterZivЭто расхожее заблуждение.На x86 - можно, в общем случае - нет. Ок?

Можно на чём-то типа i80286/386 .
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327789
MasterZiv?пропущено...
На x86 - можно, в общем случае - нет. Ок?Можно на чём-то типа i80286/386 .
Считающие себя умными - такие считающие
За весь топик лишь свои никчемные и неверные оценки: "Это верно, это неверно" и ничего больше) Царь-судья?) Или знаний 0 и по делу сказать нечего, а хочется набрать посты?)) Охохошеньки) Хотя.. у каждого свой путь к успеху)

Ну а ТСу удачи в нелегком деле освоения многопоточности!)
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327840
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
член массива,

По делу я сказал всё.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38327925
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivПо делу я сказал всё.
И даже не упомянул про выравнивание..
...
Рейтинг: 0 / 0
вопрос по потокам
    #38328726
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
MasterZiv?пропущено...
На x86 - можно, в общем случае - нет. Ок?

Можно на чём-то типа i80286/386 .На x86 не могут быть переупорядочены два чтения из памяти. Не могут быть переупорядочены две записи в память. Запись ниже по коду не может быть выполнена до чтения выше по коду. Чтение ниже по коду МОЖЕТ быть выполнено раньше записи в другой адрес выше по коду. Очень мало сценариев, где такое переупорядочение может вызвать проблему. Да, есть алгоритм Деккера , но реально его вряд ли кто-то использует при наличии атомарных обменов.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38328944
Озверин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
член массиваMasterZivпропущено...
Ошибаешься, в таком случае также безусловно нужна синхронизация.Не ошибаюсь. Если элементы являются простыми типами (32-х битное, например), то один поток может менять что хочет и как хочет, при том что другие потоки могут читать эти изменяемые элементы без синхронизации. Если же тип данных сложен и для него не существует атомарной операции для записи изменения в память (тот же double на 32-х битных системах и при размере структуры 8 байт будет записываться в элемент массива за два приема - первые 32 бита, затем вторые), то тут да, читающие потоки могут словить "полуготовое" значение, не являющееся ни старым, ни новым значением элемента, тут обязательно нужно синхронизировать читателей с писателем.

атомарность "типа" вроде же не гарантирует
а) что все операции над типом будут атомарны
б) видимость результата операции для всех потоков в многопроцессорной среде же...

Допустим для java хотя бы слово volatile добавить к "переменнной", чтобы приблизиться к решению.

авторНадо изменить массив, причём сделать изменения требуется вне зависимости от значений элементов массива (просто добавлять к определённым членам массива определённые извне значения, которые не зависят от массива)

Операция добавить - уже зависит от члена массива, так как сначала читает данные из массива, потом пишет.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38328967
Озверин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ayvangoНадо изменить массив, причём сделать изменения требуется вне зависимости от значений элементов массива (просто добавлять к определённым членам массива определённые извне значения, которые не зависят от массива). Надо ли использовать критические секции или что-то ещё или же при таких операциях в этом нет необходимости?

1. Можно пойти по очень простому пути: каждый поток пишет всегда только в свою ячейку массива ;) Почитайте про Ring Buffer - он может натолкнуть вас на решение.
2. Если уже данность, что в 1у ячейку массива могут писать несколько потоков, пойти по наиболее простому пути:
-отдельная блокировка на писателей
-отдельная блокировка на читатетей
по всему массиву
3. Если производительность не позволяет пойти по пути "2", то есть пойти почитать про то, как работает ConcurrentHashMap - там данные сегментированы, и потому блокирует не всю коллекцию, а некий сегмент с элементами(допустим с индексом от 0 до 10).


Я думаю стоит начать с простого+покрыть тестами по производительности, чтобы уже идти в сторону сложных алгоритмов.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38330250
Озверинчлен массивапропущено...
Не ошибаюсь. Если элементы являются простыми типами (32-х битное, например), то один поток может менять что хочет и как хочет, при том что другие потоки могут читать эти изменяемые элементы без синхронизации. Если же тип данных сложен и для него не существует атомарной операции для записи изменения в память (тот же double на 32-х битных системах и при размере структуры 8 байт будет записываться в элемент массива за два приема - первые 32 бита, затем вторые), то тут да, читающие потоки могут словить "полуготовое" значение, не являющееся ни старым, ни новым значением элемента, тут обязательно нужно синхронизировать читателей с писателем.

атомарность "типа" вроде же не гарантирует
а) что все операции над типом будут атомарны
б) видимость результата операции для всех потоков в многопроцессорной среде же...

Допустим для java хотя бы слово volatile добавить к "переменнной", чтобы приблизиться к решению.

a) атомарных операций только 8: load, store, add, sub, and, or, xor, cas. Первые 7 выполняются, как wait-free. Любые более сложные операции можно реализовать атомарно через cas, как lock-free.
б) Гарантия volatile слабее, чем atomic - они оба отменяют переупорядочивание, но только atomic ещё гарантирует атомарность. Видимость же в многопроцессорной среде обеспечивается соответствующими барьерами памяти, тут volatile вообще не в тему.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38330251
volatile вообще не в темуб) Гарантия volatile слабее, чем atomic - они оба отменяют переупорядочивание
Точнее даже они оба сами по себе не отменяют переупорядочивание, а только отменяют жесткую оптимизацию, которая могла бы совсем выкинуть эти инструкции.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38330578
Озверин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
volatile вообще не в темуvolatile вообще не в темуб) Гарантия volatile слабее, чем atomic - они оба отменяют переупорядочивание
Точнее даже они оба сами по себе не отменяют переупорядочивание, а только отменяют жесткую оптимизацию, которая могла бы совсем выкинуть эти инструкции.

вы сами себе противоречите..видимость как раз в разрезе оптимизации ;)
еще раз основной тезис: атомарность абсолютно не снимает проблем видимости(поток кэширует переменную и работает с локальной копией), отсюда volatile . Про переупорядочивание я вообще ничего не писал.я лишь подразумевал, что атомарность
а) ничего не решает в данном контексте
б) чтобы был намек на решение, надо хотя бы volatile добавить.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38330583
Озверинvolatile вообще не в темупропущено...

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

вы сами себе противоречите..видимость как раз в разрезе оптимизации ;)
еще раз основной тезис: атомарность абсолютно не снимает проблем видимости(поток кэширует переменную и работает с локальной копией), отсюда volatile . Про переупорядочивание я вообще ничего не писал.я лишь подразумевал, что атомарность
а) ничего не решает в данном контексте
б) чтобы был намек на решение, надо хотя бы volatile добавить.
а) Атомарность в контексте языка - это std::atomic, который отменяет жесткую оптимизацию - ему не нужен никакой volatile
б) volatile никак не решает проблему видимости между потоками. Проблему видимости решают барьеры std::memory_order.

Если метафорично: вы предлагаете пачку с солью(std::atomic) подсолить(volatile), чтобы она стала сладкая(observe modifications).
...
Рейтинг: 0 / 0
вопрос по потокам
    #38332248
Озверин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
volatile вообще не в темуОзверинпропущено...


вы сами себе противоречите..видимость как раз в разрезе оптимизации ;)
еще раз основной тезис: атомарность абсолютно не снимает проблем видимости(поток кэширует переменную и работает с локальной копией), отсюда volatile . Про переупорядочивание я вообще ничего не писал.я лишь подразумевал, что атомарность
а) ничего не решает в данном контексте
б) чтобы был намек на решение, надо хотя бы volatile добавить.
а) Атомарность в контексте языка - это std::atomic, который отменяет жесткую оптимизацию - ему не нужен никакой volatile
б) volatile никак не решает проблему видимости между потоками. Проблему видимости решают барьеры std::memory_order.

Если метафорично: вы предлагаете пачку с солью(std::atomic) подсолить(volatile), чтобы она стала сладкая(observe modifications).

В разрезе какого языка?:) Тут программирование и как бе атомарными могут быть типы, машинозависимые..вы о чем вообще?))))
...
Рейтинг: 0 / 0
вопрос по потокам
    #38332531
Озверинvolatile вообще не в темупропущено...

а) Атомарность в контексте языка - это std::atomic, который отменяет жесткую оптимизацию - ему не нужен никакой volatile
б) volatile никак не решает проблему видимости между потоками. Проблему видимости решают барьеры std::memory_order.

Если метафорично: вы предлагаете пачку с солью(std::atomic) подсолить(volatile), чтобы она стала сладкая(observe modifications).

В разрезе какого языка?:) Тут программирование и как бе атомарными могут быть типы, машинозависимые..вы о чем вообще?))))
О том что типы не могут быть атомарными, т.к. если нет выравнивания то никакой атомарности ни для каких типов не будет. Кроме 1-байтных, т.к. тут всегда есть выравнивание.
...
Рейтинг: 0 / 0
вопрос по потокам
    #38341475
Фотография tchingiz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
самодельный логгер. сишарп

Код: c#
1.
2.
3.
4.
5.
6.
7.
    public class Logger:IDisposable
    {
        public Queue StringQueue = new Queue();
        MsgLevel ILevel;
        bool Working = false;

.....



несколько ниток пишут в один и тот-же логгер // используется очередь
одна читает из очереди и выводит в файл.

в функции, которая пишет в логгер, надо блокировать все переменные (1) или достаточно блокировать собственно только запись в очередь и не вносить локальные переменные метода в блокировку (2)?

1 версия

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
       public void WriteLine(MsgLevel Importance, String Format, params object[] pars)
        {
            if (Working && Importance >= this.ILevel)
            {
                lock(this) {
                  String Date = "[" + DateTime.Now.ToString()+ "] ";
                  String Message = Date + String.Format("[{0}]\t", Importance) +"\t"+ string.Format(Format, pars);
                  StringQueue.Enqueue(Message);
                }
            }
        }



2 версия

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
       public void WriteLine(MsgLevel Importance, String Format, params object[] pars)
        {
            if (Working && Importance >= this.ILevel)
            {

                  String Date = "[" + DateTime.Now.ToString()+ "] ";
                  String Message = Date + String.Format("[{0}]\t", Importance) +"\t"+ string.Format(Format, pars);
                lock(this) {
                    StringQueue.Enqueue(Message);
                }
            }
        }
...
Рейтинг: 0 / 0
34 сообщений из 34, показаны все 2 страниц
Форумы / Программирование [игнор отключен] [закрыт для гостей] / вопрос по потокам
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]