> > Смотря какая природа у этого варианта. У меня сейчас два потока > > работают > > - один грузит данные из базы > > - второй эти данные обрабатывает. > > В идеале первый поток не нужен.
Странные у тебя идеалы :) > Я бы сделал работу следующим образом: поток-читатель считывает из базы > блок данных и передаёт его на обработку второму потоку через > PostThreadMessage (по старинке) или QueueUserAPC (по современному). > Размер блока данных подбирается чтобы его обработка занимала примерно > полсекунды. Я это сделал через "буфер обмена", защищенным критческой секцией. > > проблема в том, что первый успевает насытить буфер с исходными данными > > под завязку, а второй пашет как ненормальный что бы этот буфер > > освободить, но очень редко когда его опустошает. > > А проблема то в чем? Конечно, при любых алгоритмах нужно приостанавливать > фетч если данные обрабатываются медленно. Он у меня приостанавливается :) У меня даже фоновый поток выгрузки модифицированных страниц может завершаться, когда у него нет работы. Правда, работой его по самую макушку заваливают. > И ещё, получается что у тебя обработка данных занимает времени намного > больше чем их выкачка из базы. В такой ситуации выигрышь от > распараллеливания невелик в процентом отношении. Иногда "буфер" все таки опустошается. Это когда сервер начинает чухаться с подгрузкой нужной части данных в свой кэш. ------- Вообщем, текущее положение дел с "машиной тьюринга" такое. - Я прикрутил фоновый поток выгрузки модифицированных страниц. - Послушал как работает машина (в натуре на слух), и понял - нужно нафиг отключить буферизацию файловых операций. То бишь указал флаги FILE_FLAG_WRITE_THROUGH, FILE_FLAG_NO_BUFFERING - Это потребовало заюзать память, выделяемую через VirtualAlloc. Типа, как завещал Великий LOA :) - Гудение винтов стало равномерным :) (кстати пару раз слышал странные щелчки) - Посмотрев на это дело, я понял что бежать больше некуда и надо доделывать менеджер кэша - в него писать не через read/write функции, а напрямую. И переделать управление хеш-таблицей - отказаться от мелких блоков, а перейти к блокам занимающим всю страницу целиком. Продолбенился над реализацией целый день. Получилось красиво. И - о чудо! У меня многопоточная реализация стала работать вровень с однопоточной. Более того - может это меня заглючило (в 3 часа ночи) - даже немного быстрее. Вообщем, системные затраты стали очень маленькими и диспетчер задач светился радостным зеленым цветом. Одним из забавных моментов была при обработке какой-то порции данных, когда общая нагрузка на процессор (HT включен) плавно поднималась с 50 до 100, там держалась, а потом плавно опускалась. Возможно это связано с увеличением числа попаданий в локальные кэши каждого потока. Хотя по правде - шайтан его знает, с чем это связано. ---------- Но, плят, щастье длится ровно столько сколько заполняется кэш. Напомню, мне нужно построить уникальный индекс для (по последним прогнозам) 100 лимонов элементов вида (ID1, ID2). Максимум что я смог осилить - 20 лимонов. Сейчас, для построения индекса элементов, юзаю хеш-таблицу. По формуле (ID1+ID2)/HashTableSize определяю элемент таблицы. В элементе хранится указатель на упорядоченный блочный список. Блок списка равен размеру страницы (4K). Фоновый поток выгружает самые старые модифицированные страницы. Но, судя по индикации счетчиков размеров списков "чистых" и "грязных" страниц, в эти "очищенные" страницы сразу же срут и они возвращаются в очередь "грязных" страниц. Скорость генерации очень высокая - программа только начинает работать, а уже сразу выжирает под 30-40 тысяч страниц. И дальше очень интенсивно гадит в каждую из них. После заполнения кэша (я эксперементирую с кэшем на 120 тыс четырех килобайтных страниц) производительность падает до копеечных размеров. Я пробовал останавливать потоки генерации, что бы дать "выгружателю" сбросить все на диск - эффект мизерный. После того как "генераторы" возобновляют работу - производительность не повышается и очередь грязных страниц неулонно растет. Это зарезало мою идею уменьшать приоритет генераторов при катастрофическом загрязнении кэша. Пробовал играть и с размером страниц и c HashTableSize - общая картина не улучшается. ---------- Мне кажется что проблема все таки в самой hash-таблице. Точнее в стоимости добавления нового элемента в существующий список. Если программа способна генерировать свыше 20 тыс уникальных комбинаций в секунду, и каждая из них попадает в свой список хеш-таблицы, то тут ничего не спасет. Я же, блин, постарался - отсортированность поддерживаю. Так что тут еще и уже заполненные блоки списков могут модифицироваться... Сейчас буду прикладывать к голове умную книжку с описанием конструкции Б-деревьев. ---------- Не, но многоточность я таки победил. Честное пионерское :) ... Как сложно делать простые вещи. И какими сложными они потом оказываюся :( Коваленко Дмитрий.

