Russian Qt Forum
Май 16, 2024, 09:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: 1 ... 720 721 [722] 723 724 ... 761
10816  Qt / Общие вопросы / Re: Параллельные вычисления (проблемы) : Декабрь 10, 2009, 13:27
Добрый день

Подсобрал статистику http://www.2shared.com/file/9869897/e1de3de1/stat.html (к сожалению, прикрепить здесь не удается).

Запущены 4 нитки. Для каждой точки выполняется N расчетов (первая колонка таблицы). Расчеты могут быть более или менее трудоемкие (таблицы 1, 2 и 3) в зависимости от объема исходных данных. В таблицах представлены худшие (для меня) варианты. Когда 1000 вычислений на точку и/или каждый расчет трудоемок - все хорошо, наступает эффект "в разы". А вот когда вычислений маловато - проблемы.

В таблицах указано время (в секундах) и коэффициент выигрыша (по отношению к версии где все выполняется в главной нитке). Столбцы "job = " показывают размер "пачки", т.е. порцию вычислений для каждой нитки. На первый взгляд (из общих соображений) чем больше пачка - тем лучше. Но на деле совсем не так.

Чего-то важного я здесь не понимаю. Может быть, поизучать исходники OpenMP - других идей пока нет.

10817  Qt / Общие вопросы / Re: Потоки (прервать или продолжить) : Декабрь 10, 2009, 11:45
Страшная функция - не оптимизирована страшно, краткая характеристика. Думаю как упрастить.
Что можна заменить на более быстродействующее?
Смысл работы: передаю список выделений итемов, составляю список выделенных колонок и строк; по этому списку формирую список итемов для сортировки, сортирую полученный список и устанавливаю эти итемы в выделенные колонки/строки. Списков много, как уменьшить. Преимущество такой сортировки ячеек для таблицы - могу сортировать разные колонки, находящиеся не рядом (поэтому и список выделений selectionRange) и могу выделять ячейки с помощью Ctrl , недостатки для колонки 10000 итемов сортирует долго
Кто чем может помогите? Грустный
10 тысяч итемов - для сортировки не объем, если Вы сортируете грамотно это должно выполняться за доли секунды. Для начала проверьте что все списки/контейнеры подаются по ссылке. Не поможет - выкладывайте Вашу "страшную ф-цию", будем смотреть.
10818  Qt / Общие вопросы / Re: Потоки (прервать или продолжить) : Декабрь 10, 2009, 01:13
У меня в конце той страшной функции вызывается функция  somethingChanged(), которая тоже долго вычисляется. Как тогда быть в таком случае с прогресс диалогом (проверкой на отмену)? Ну например ещё qSort...
UpdateProgress(progress, i)
Ну и подайте ей progress (QProgressDialog) как аргумент, напр. опишите ее так
Код:
bool somethingChanged( QProgressDialog & progress );

// вызов
if (!somethingChanged(progress)) return false;

А внутри ф-ции работайте в том же стиле, заряжайте индикатор и все дела. Насчет сортировки - да, это не обновит индикатор, ну так что с того - не все операции могут быть прерваны, это нормально. И вообще, что это за философия такая "страшная ф-ция" и.т.п? Это они должны Вас бояться а не Вы их Улыбающийся
10819  Qt / Общие вопросы / Re: Потоки (прервать или продолжить) : Декабрь 09, 2009, 23:00
Как по мне надо сделать маленькие изменения
Код
C++ (Qt)
if ((row+1 ) % UPDATE_STEP) return false;
if (UpdateProgress(progress, it)) return false; каждую проверку заменить
Почему нет? Но тогда измените название - не UpdateProgress, а, например, UserCancel.

И еще: не прессуйте текст типа (row+1) - это выглядит как зажатый зародыш в утробе матери Улыбающийся Что Вам, пробелов жалко? Пишите со вкусом, покажите всем что Вы хотели сказать, не жмитесь к стенке Улыбающийся
10820  Qt / Общие вопросы / Re: Параллельные вычисления (проблемы) : Декабрь 09, 2009, 16:05
2BRE
На его картинке, показанно 223 потока Шокированный Надеюсь что его потоков много меньше Подмигивающий
Если же его потоков большенство, то тут в серьез стОит задуматься над другим алгоритмом.
Улыбающийся Это просто Activity Monitor показывает все threads в системе. Я предлагаю пользователю ввести число ниток, по умолчанию = числу процессоров. То есть в данном случае - всего 4. (+главная)

Igors, а ты не смотрел в сторону OpenMP? Конечно, если есть такая возможность.
Возможность есть, у XCode это даже 1 из опций компилятора (правда не знаю про Вындоуз). Почему не смотрю - не понимаю как он может здесь помочь, я вижу какие места не могут быть распараллелены. Базовый механизм один для всех (может я неправ)
10821  Qt / Общие вопросы / Re: Параллельные вычисления (проблемы) : Декабрь 09, 2009, 14:41
Мои мысли по данному вопросу складываются из двух твоих тем: про GetPixel и потокобезопастностm простых операций.... Может я и ошибаюсь....
Мне кажется, что такое поведение складывается из-за того, что сами задачи, которые выполняют нити ничтожны по сравнению с оверхедом от использования методов синхронизации. Т.е. если нить, грубо говоря, делает пару умножений и пару сложений и при этом использует операции синхронизации (тот же mutex), то ты больше времени тратишь на переключения контекста и ожидание, чем на сами вычисления. Думаю по этому и однопоточная версия выполняется быстрее.
Наверное лучше нагружать нити посильнее, например обрабатывать не по одному пикселю, а массивами пикселей. Играясь с размерами массивов, можно будет подбирать оптимальную нагрузку на ядра. Кстати, я уже предлагал такое решение в теме про GetPixel.
Ну если бы можно было все разбить на N независимых кусков и дать каждой нитке по куску - я бы с удовольствием так и сделал. Как говорил классик "съесть конечно он бы съел да только кто ж ему даст?" Улыбающийся Многие (самые трудоемкие) данные пикселей интерполируются, зависят друг от друга. Простой пример: есть квадрат из пикселей, напр. 4х4. Посчитали углы, посмотрели разброс значений. Достаточно мал - отлично, пошли дальше. Нет - разбиваем на 4 суб-квадрата и парим каждый. Расчет данных одного пикселя совсем не сводится к вычислению текстур (картинок) - это просто фрагмент расчета который должен быть thread-safe. Для каждого пикселя производится 200 и более расчетов (выбросов лучей). Они-то и потребляют 95% (и более) всего времени. Вот я и делаю чтобы эти 200 выполнялись в разных нитках. Понимаю что др. подходы также возможны, но каждый имеет свои минусы. Например, разбив все пиксели на какие-то "большие квадраты/полосы" я получу головную боль с их "сшивкой". Плюс эти квадраты могут требовать совершенно разных вычислений.

Разумеется, расчеты объединены в "пачки" и я могу варьировать ее размер. Трудоемкость одного пикселя: 80К пикселей рассчитываются за 32 сек (1 процессор). Общие ресурсы - для простоты скажем "отсутсвуют". Диаграмма нагрузки (4 нитки) здесь http://www.2shared.com/file/9838740/b1147927/Picture_2.html
10822  Qt / Общие вопросы / Re: QPainter::drawPixmap - похоже конкретный Баг? : Декабрь 09, 2009, 13:24
Я так понял 2 painter'а (Painter и painter). Первый рисует в pixmap, второй ее выводит. Если так то интересно проверить:
Код
C++ (Qt)
QPixmap Pixmap(10, 10);
if (1) {
 QPainter Painter(Pixmap);
 
 Painter.fillRect(Pixmap.rect(), Qt::green); // GREEN 10*10
 
 Painter.fillRect(QRect(0,0,1,10), Qt::red); // RED 1*10 + GREEN 9*10
}
painter.drawPixmap(QRect(1,0,9,10), *pixmap, QRect(0,0,9,10)); // QT BUG
 
10823  Qt / Общие вопросы / Re: Параллельные вычисления (проблемы) : Декабрь 08, 2009, 23:45
Какая там общая память (shared memory) в задаче и для семафор? Один промах в cache (memory-miss) стоит очень много вычислений! Эрудиция моя такая: на семафорах он ждёт страницу из общей или дальней памяти, а все вычисления происходят в презагруженных регистрах или презагруженной cache.

То есть, критическая роль в данном случае - это скорость памяти а не процессора.
 Непонимающий 
Понял, отвечаю. Shared memory в задаче есть но для тестирования полностью отключена. Все происходит в памяти процесса. Были проверены 3 варианта семафоров (OSX)

1) sem_open (BSD named semaphore)
2) semaphore_create (POSIX семафор если не путаю)
3) QSemaphore (Qt)

1 и 2 дают тот же результат, 3 немного слабее - но общая картина та же.
10824  Qt / Общие вопросы / Параллельные вычисления (проблемы) : Декабрь 08, 2009, 21:45
Добрый вечер

Занимаюсь задействованием всех процессоров для долгих вычислений и столкнулся с проблемой.
Процессор Intel Xeon (2 процессора по 2 ядра).  Сделал механизм для ниток, семафоры - все необходимое. Результаты получаются такие:

1) Подставляю "тестовые расчеты" (т.е. проверяю сам механизм). Результаты разумные: на 4-х нитках время более чем в 2 раза меньше (по сравнению с начальной "безниточной" версией) . Понимаю что не все распараллелено, да что-то еще съедят семафоры, так что нормально.

2)  Подставляю "рабочие расчеты" (как они в задаче). Результат - время на 4-х нитках даже несколько БОЛЬШЕ исходного. Хотя все вычисления выполняются правильно, результаты совпадают. В чем дело? Смотрю в tools (OSX). CPU Sampler (по простому говоря профайлер) показывает - время ожидания на семафорах резко возросло. Activity Monitor показывает - значительная часть процессорного времени была съедена системой - непонятно для чего.

Но самое забавное - при использовании профайлера/tools время становится .. заметно меньше! (на 25% как минимум). Перепроверил много раз.

Понимаю что "нужно смотреть расчеты". Ну это сотни файлов и привести их здесь нет возможности. Да и что смотреть? Разумеется я все упростил как мог: отключил I/O, все вызовы OC и.т.п. Но эффект остается.

Идеи, опыт, эрудиция?

Спасибо
10825  Qt / Общие вопросы / Re: Потоки (прервать или продолжить) : Декабрь 08, 2009, 15:04
Can you read or only write? Улыбающийся

Вам говорили что диалог должен быть модальным? Просто слушайте и понимайте - и массы вопросов не возникнет. Не надо ничего разбивать, просто заряжайте индикатор для каждой операции, например

Код:
#define UPDATE_STEP	100

bool UpdateProgress( QProgressDialog & progress, int row )
{
if ((row + 1) % UPDATE_STEP) return true; // update once per UPDATE_STEP
progress.setValue(row); // calls processEvents for modal dialog
return progress.wasCanceled();
}

bool Spreadsheet::sort_data( const QList<QTableWidgetSelectionRange> & range, const SpreadsheetCompare & compare )
{
if(range.isEmpty()) return false;

QProgressDialog progress(this);
progess.setModal(true); // should be modal

// check range
progress.setLabelText(tr("Checking range"));
progress.setMaximum(range.size());
for (int it = 0; it < range.size(); it++) {
if (range[it].leftColumn() < 0) return false;
if (range[it].bottomRow() < 0) return false;
if (range[it].rightColumn() < 0) return false;
if (range[it].topRow() < 0) return false;
if (!UpdateProgress(progress, it)) return false;
}

// fill columns
QList<int> columns;
QList<int> rows_n;

progress.setLabelText(tr("Adding rows & columns"));
progress.setMaximum(range.size());
progress.setValue(0);
for(int i = 0; i < range.size(); i++) {
for (int col = range[i].leftColumn(); col <= range[i].rightColumn(); col++)
  if (columns.indexOf(col) == -1) columns.push_back(col);

for(int row = range[i].topRow(); row <= range[i].bottomRow(); row++)
if (rows_n.indexOf(row) == -1) rows_n.push_back(row);

if (!UpdateProgress(progress, i)) return false;
}

// sort
progress.setLabelText(tr("Sorting"));
progress.setMaximum(2);
progress.setValue(0);
qSort(columns.begin(), columns.end());
qSort(rows_n.begin(), rows_n.end());

// add
progress.setLabelText(tr("Adding rows & columns"));
progress.setMaximum(rows_n.size());
progress.setValue(0);
QList<QStringList> rows;
for(int i = 0; i < rows_n.size(); i++) {
if (!UpdateProgress(progress, i)) return false;
QStringList row;
for (int j = 0; j < columns.size(); j++) {
  if (is_item_in_list_selection_range(range, rows_n[i], columns[j])) {
if (isError_in_cell(rows_n[i], columns[j]))
return false;
if (item(rows_n[i], columns[j]))
  row.push_back(text(rows_n[i], columns[j]));
}
}

if (row.size() == columns.size() && row.size() > 0)
rows.push_back(row);
else {
rows_n.removeOne(rows_n[i]);
i--;
}
row.clear();
}

QList<QStringList> temp = rows;
qStableSort(rows.begin(), rows.end(), compare);
if (rows == temp) return false;

// set items
progress.setLabelText(tr("Setting Items"));
progress.setMaximum(rows.size());
progress.setValue(0);
for (int i = 0; i < rows.size(); i++) {
if (!UpdateProgress(progress, i)) return false;
for(int j = 0; j < rows[i].size(); j++)
setItem(rows_n[i], columns[j], rows[i][j]);
}
 
return true;
}
10826  Qt / Общие вопросы / Re: Потоки (прервать или продолжить) : Декабрь 07, 2009, 22:19
Можна как-то обойтись именно в функции без прогрессдиалога и светить после выполнения части задачи сигналом value
А в функции, которая вызвала этот слот сделать connect с этим сигналом value и соединить с прогрессдиалогом на вывод текущего прогресса. Но тут проблема как прервать работу той страшной функции в слоте с коннектом.
Зачем "обходиться" без вещи которая делает именно то что Вам нужно? QProgressDialog уже "светит", просто давайте ему setProgress (см. ссылку)

Как распределить показание прогрессдиалога? Может условно поделить свою функции на проценты выполнения
Объявите в начале ф-ции QProgressDialog progress. К каждому processEvents в Ваших ф-циях добавьте:
Код:
 progress.setProgress(it);
..
 qApp->processEvents();
 if (progress.wasCanceled()) {
      return false;
 }
Сделайте это, потом задавайте очередные вопросы (если они возникнут).
10827  Qt / Общие вопросы / Re: Потоки (прервать или продолжить) : Декабрь 07, 2009, 21:39
Это две самые страшные функции одна вызывает другую (запускаю слот sort_data_with_GUI(const QList<QTableWidgetSelectionRange>& range) (1 из функций) из mainWindow)
Спасибо за ссылку, хорошо для одного цикла в функции, а как быть с разными операциями в функции

Задача изначально была такова- выполняется функция (долгая операция), если пользователь запускает на выполнение другую операцию выводится сообщение: "Прервать или продолжить?", тоже самое и при закрытии окна при выполнении задачи. При подтверждении прерывания желательно было бы откатить то, что сделала функция (не обязательно), а так прервать выполнение функции; продолжить - продолжение выполнение той задачи. Заранее большое спасибо, хочу сделать просто хорошее приложение (обработать все возможные нюансы).
Объясните ЗАЧЕМ Вы даете пользователю возможность что-то нажимать если текущая операция не закончена? Все гораздо проще, не придумывайте себе проблем. Началась трудоемкая операция - покажите индикатор QProgressDialog. А поскольку он модальный (см. ссылку) то единственное что пользователь может сделать - нажать cancel и Вы легко это можете отловить (см. ту же ссылку). Все остальное будет зажато модальностью индикатора. Надо переспросить пользователя - не проблема, породитесь от QProgressDialog. Надо откатить операцию - у Вас все на руках, одно удовольствие. Не лезьте в асинхронку, потом полжизни на аптеку будете работать  Улыбающийся
10828  Программирование / С/C++ / Re: как ограничить float? : Декабрь 07, 2009, 12:54
Код:
qreal V=0.01*floor(100*(Vol)+0.5);
Не попрет с отрицательными числами Улыбающийся А вообще navrocky прав: с round покороче будет - не знал что есть такая удобная ф-ция, спасибо.

советую использовать qreal вместо float, если же конечно не под ARM процы пишешь.
http://www.ibm.com/developerworks/ru/library/l-qt_2/index.html
Не жирно ли будет для хранения данных? Люди 16-битный float используют вовсю...
10829  Компиляторы и платформы / Mac OS X / Re: Leopard не могу найти make : Декабрь 07, 2009, 11:34
Я ничего нигде не прописывал. Стоял XCode 3.1. Скачал qt-sdk-mac....dmg, запустил инсталлер, выбрал тот же раздел (системный) где XCode. Все поставилось, qmake запускается. Есть проблемы с XCode но то уже др. вопрос, а так ходит.
10830  Qt / Общие вопросы / Re: Потоки (прервать или продолжить) : Декабрь 07, 2009, 10:56
Изначально вопрос был
Как на момент выполнения трудоемкой задачи заблокировать сигналы от кнопок, закрытие окна.....?
Это решается несколькими способами, например очень хорошо смотрится QProgressDialog. Вот старая но хорошая ссылочка http://www.opennet.ru/docs/RUS/qt3_prog/x4064.html

daimon, все что Вам нужно это переписать текст из примера (или выложите ф-цию, я добавлю текст). Это займет 5 минут и совершенно незачем вдаваться в нюансы потоков и.т.п. Это не имеет к Вашей задаче никакого отношения.
Страниц: 1 ... 720 721 [722] 723 724 ... 761

Страница сгенерирована за 0.113 секунд. Запросов: 23.