Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Подскажите как искать лажу в проге

4.6K
01 июля 2010 года
WildCat
15 / / 05.11.2003
Есть 2 варианта некоторой библиотеки (lib), в одном варианте все работает последовательно и вроде как правильно.

Для ускорения работы решила распараллелить по нитям и тут результаты стали получаться другие.

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

Вот 2 варианта кода:
Последовательный:
 
Код:
for (unsigned numcl = 0; numcl < classifiers.size(); numcl++) {
        classifiers[numcl]->loadSample(d);
        classifiers[numcl]->classifyProb();
        resultProb[numcl] = classifiers[numcl]->getOutputValue();
    }


Параллельный:
Код:
HANDLE* threadHandles = new HANDLE [classifiers.size()];
    for (unsigned numcl = 0; numcl < classifiers.size(); numcl++) {
        ThreadParamsProcessor *prms = new ThreadParamsProcessor;
        prms->cl = classifiers[numcl];
        prms->d = &d;
        prms->multiplier = &(resultProb[numcl]);

        CWinThread *pThread = ::AfxBeginThread(ThreadProcessImppr, prms);
        threadHandles[numcl] = pThread->m_hThread;
    }

    ::WaitForMultipleObjects(classifiers.size(), threadHandles, TRUE, INFINITE);


Среда VS2008

Подскажите, где искать и что искать...
4.6K
01 июля 2010 года
WildCat
15 / / 05.11.2003
Кажется в версии с нитями глючно работает Wait, и раньше я тоже где-то с этим встречалась, но так и не нашла решения данной проблемы....

Хотя может все и не от этого. Я такой вывод сделала когда стала выводить внутреннии параметры классификаторов, а печать пошла уже после того, как напечателся конечный резуль, а ее ответ уже ушел...
4.6K
02 июля 2010 года
WildCat
15 / / 05.11.2003
Продолжу разговор сама с собой... (Всегда приятно поговорить с умным человеком ;) )

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

Вот пример работающего кода с нитями:
Код:
vector <CWinThread*> objThreads;
    vector <HANDLE> hThreads;
    objThreads.reserve(classifiers.size());
    hThreads.reserve(classifiers.size());

    for (int numcl = 0; numcl < (int)classifiers.size(); numcl++) {
        ThreadParamsProcessor *prms = new ThreadParamsProcessor;
        prms->cl = classifiers[numcl];
        prms->d = &d;
        prms->multiplier = &(resultProb[numcl]);

        objThreads.push_back(AfxBeginThread(ThreadProcessImppr, prms, THREAD_PRIORITY_NORMAL, NULL, CREATE_SUSPENDED));
        objThreads[numcl]->m_bAutoDelete = FALSE;
        objThreads[numcl]->ResumeThread();
        hThreads.push_back(objThreads[numcl]->m_hThread);
    }

    ::WaitForMultipleObjects(hThreads.size(), &hThreads[0], TRUE, INFINITE);


Только теперь это работает не бустрее последовательного варианта, а даже чуть медленее (~10 мс), а ожидалось ускорение, хотя бы в 2 раза....

В проектах везде установлено, что они должны быть многопоточные
4.6K
02 июля 2010 года
WildCat
15 / / 05.11.2003
Дальше все любопытственнее и любопытственнее...

Сделала то же самое с использованием средств openmp, стало еще медленее...
5
02 июля 2010 года
hardcase
4.5K / / 09.08.2005
Что за библиотека и может ли она работать в многопоточном варианте?
4.6K
02 июля 2010 года
WildCat
15 / / 05.11.2003
библиотеку я сама пишу, в настройках проекта стоит, что она многопоточная.

Код, который я привожу находится как раз внутри библиотеки.

Может будет полезным:
Время обработки всеми классификаторами (6 штук) на самом деле получается (те, что в коде называются classifiers) порядка 170-200 мс. Среди них есть 2 медленных и 4 быстрых, быстрые работают за 0.05 мс, а вот все остальное время занимают медленные.
5
02 июля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: WildCat
библиотеку я сама пишу, в настройках проекта стоит, что она многопоточная.

Код, который я привожу находится как раз внутри библиотеки.

А код действительно выполняется параллельно?
Нет ли в библиотеке каких-то общих данных, обращение к которым требует синхронизации (и она происходит с эффектом - все потоки выполняются по очереди, без выигрыша в производительности)?

4.6K
02 июля 2010 года
WildCat
15 / / 05.11.2003
Наверняка сказать не могу, по логике, вроде должно быть параллельно, из общих есть только параметр d, из которого все загружается...

Приведу код самой нити:
Код:
struct ThreadParamsProcessor {
    float *multiplier;
    IClassifier *cl;
    const DBSampleData *d;
};

UINT ThreadProcessImppr(LPVOID pParam) {
    ThreadParamsProcessor *prm = (ThreadParamsProcessor*)pParam;
    prm->cl->loadSample(*(prm->d));
    prm->cl->classifyProb();
    *(prm->multiplier) = prm->cl->getOutputValue();

    delete prm;
    return 0;
}


Классификаторы все свои внутренние данные содержат отдельно внутри, каждая нить работает со свои классификатором.

Есть только идея, что картинка, содержащаяся в d (DBSampleData) может не обрабатываться параллельно, но вообще-то ко всем данным в d обращаюсь только для чтения.
5
02 июля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: WildCat

Есть только идея, что картинка, содержащаяся в d (DBSampleData) может не обрабатываться параллельно, но вообще-то ко всем данным в d обращаюсь только для чтения.


Идем дальше. Что за изображение?

4.6K
02 июля 2010 года
WildCat
15 / / 05.11.2003
Вот структура DBSampleData

 
Код:
struct DBSampleData {
    float *dpca;
    float *eigenf;
    float *gabor;
    char *picFileName;
    IImagePreprocessor *imppr; // - это то самое изображение, точнее его обертка
    float *pc2a;
    float *pca;
};


Оберткуа изображения к проекту также подключается в виде библиотеки (lib), она тоже самописная, многопоточность поддерживает.

Внутри обертки обрабатываемое изображение содержится в виде OpenCV - IplImage*.

Раньше, вроде параллелила куски кода с OpenCV, проблем не было ускорение достигалось.
4.6K
02 июля 2010 года
WildCat
15 / / 05.11.2003
И огромное, спасибо за помощь в разборе полетов :)
5
02 июля 2010 года
hardcase
4.5K / / 09.08.2005
Глянул на IplImage, видимо всетаки проблема не в нем.
Кстати, примерное время работы - 200мс - это уже достаточно короткий промежуток времени при обработке одного изображения. Вообще запуск потока сама по себе небыстрая операция, потому вы возможно просто не замечаете ускорения. А вот OpenCV мог работать с уже изготовленными потоками, например из собственного пула.
4.6K
02 июля 2010 года
WildCat
15 / / 05.11.2003
Цитата: hardcase

Кстати, примерное время работы - 200мс - это уже сам по себе достаточно короткий промежуток времени при обработке одного изображения. Вообще запуск потока сама по себе небыстрая операция, потому вы возможно просто не замечаете ускорения. А вот OpenCV мог работать с уже изготовленными потоками, например из собственного пула.



Да на самом деле то, что я распараллеливала раньше - были более массивные куски кода, я написала это в качестве аргумента, что OpenCv должен нормально работать с нитями.

Может и вправду тут уже за счет нитей не получится ускориться...

5
02 июля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: WildCat
Может и вправду тут уже за счет нитей не получится ускориться...


Вы обрабатываете одно изображение или множество?
Если множество, то имеет смысл сделать рабочие потоки которым отдавать эти изображения, каждое из которых будет проходить в своем потоке последовательно через классификаторы.

4.6K
02 июля 2010 года
WildCat
15 / / 05.11.2003
Пока надо сделать модуль, который обрабатывает по 1 изображению, а то как я раньше распараллеливала - как раз обрабатывала набор изображений, деля его по потокам.
5
02 июля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: WildCat
Пока надо сделать модуль, который обрабатывает по 1 изображению, а то как я раньше распараллеливала - как раз обрабатывала набор изображений, деля его по потокам.


Я думаю тогда ваш дизайн распараллеливания нужно пересмотреть. Незачем для каждого изображения при каждом запросе порождать 6 потоков. Заранее создайте набор из нужного количества потоков и передавайте им данные. Для синхронизации вам потребуется евент (для единомоментного запуска обработки данных в потоках) и семафор - для ожидания о завершения обработки данных.
Другим способом может быть использование пула потоков, предоставляемого системой (он будет походить на то что у вас сейчас).

4.6K
05 июля 2010 года
WildCat
15 / / 05.11.2003
Спасибо за совет, но такая система показалась довольно сложной и это заставило еще раз посмотреть на существующие классификаторы. Оказалось, что основное время занимает только 1 классификатор, а остальные достаточно быстрые, поэтому время и не уменьшалось. Внедрила распараллеливание внутрь этого классификатора. За счет этого удалось уменьшить время работы до ~70 мс (при распараллеливании с помощью openmp). Если написать ручками можно еще чуть-чуть уменьшить, но думаю на данный момень такой показатель - уже хорошо.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог