2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу Пред.  1 ... 3, 4, 5, 6, 7, 8, 9 ... 14  След.
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение04.01.2020, 21:27 
slavav в сообщении #1433433 писал(а):
надо сделать программу корректной. Не "она выдает один и тот-же результат", а корректной-корректной

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

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение04.01.2020, 21:33 
1. Рекомендую все массивы заменить на вектора, а обращения к ним на вызов vector::at.
2. Рекомендую ещё выполнить вот такое преобразование кода программы: ...

-- 04.01.2020, 21:35 --

Andrey_Kireew в сообщении #1433437 писал(а):
Вы выражаетесь слишком туманно, что значит корректной- корректной? И с чего Вы взяли, что моя программа такой не является, даже её не видя?

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

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение04.01.2020, 21:38 
Andrey_Kireew в сообщении #1433429 писал(а):
По многочисленным просьбам представляю код программы
Ну я никакого криминала не вижу. Предположил бы что это new так недетерменировано тормозит, но Вы говорили оно не влияет. В циклах память не выделяется и не освобождается. Почему не получается ускорения для более 2 потоков не вижу причин в данном коде.

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение04.01.2020, 22:11 
Прошу прощения что сорвался выше и употребил выражение "...".
Нужен полный код программы или пока его нет...
Скорее всего вы пишете мимо массивов. Память портится и потоки влияют друг на друга.
Вынесите вычислительный код в отдельный файл так, чтобы его можно было задействовать и в многопоточной и в однопоточной программах.
Пропустите код через статический анализатор.
Пропустите код через valgrind.
Все массивы замените на классы в проверкой выхода за пределы массива. Если вас беспокоит производительность (это зря, но вдруг), то потом, когда вы убедитесь что ошибок нет, вы можете вернуться к массивам в стиле C.
Ограничьте использование голых указателей. Где можно, переходите на индексы.
Переработайте код так чтобы в нём не было голых new/delete. (RAII).
Нашпигуйте код ассертами. (только проверьте что они работают).
Покройте код тестами. (это уже фантастика, конечно).

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение04.01.2020, 23:22 
Dmitriy40 в сообщении #1433439 писал(а):
Предположил бы что это new так недетерменировано тормозит, но Вы говорили оно не влияет. В циклах память не выделяется и не освобождается

Вот именно, выделение только в начале, а освобождение в конце. Но вот если выделить в основном потоке и передать указатели через структуру (вроде как тот же динамический массив, а предаётся только его адрес) некоторые потоки завершаются быстро, а некоторые долго пыхтят. И выходит почти как на одном ядре. Мне бы очень хотелось знать почему так выходит. Ну и static опять же непонятно ... Может к этой структуре какие то особые требования есть?

slavav в сообщении #1433444 писал(а):
Скорее всего вы пишете мимо массивов

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

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение04.01.2020, 23:39 
Andrey_Kireew в сообщении #1433455 писал(а):
Надо просто внимательнее будет код перепроверить.
Это плохая идея. Подумайте как заставить компьютер сделать эту работу. Напишите код, который сам себя проверит. Вы серьёзно считаете что ручная проверка надежнее автоматической?

-- 04.01.2020, 23:44 --

Отделите выделение/удаление массивов от основных вычислений. То есть вынесите вычисления в отдельную функцию.
Поставьте const на массивы, которые не должны меняться при вычислениях.

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение05.01.2020, 00:28 
slavav в сообщении #1433459 писал(а):
Вы серьёзно считаете что ручная проверка надежнее автоматической?

я считаю, что это быстрее и проще, а пока я буду разбираться в этом новомодном софте - пройдут недели,а то и месяцы
slavav в сообщении #1433459 писал(а):
Отделите выделение/удаление массивов от основных вычислений

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

Dmitriy40, забыл уточнить - зависание происходит уже при выходе из потоков, время вычислений уже успевает отобразиться на экране. Где там вообще может что зависнуть, не знаете?

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение05.01.2020, 00:42 
Andrey_Kireew в сообщении #1433466 писал(а):
slavav в сообщении #1433459 писал(а):
Вы серьёзно считаете что ручная проверка надежнее автоматической?

я считаю, что это быстрее и проще, а пока я буду разбираться в этом новомодном софте - пройдут недели,а то и месяцы
Я говорил об изменении кода программы так, чтобы в случае обращения вне границ массива программа немедленно сообщала об ошибке.
Andrey_Kireew в сообщении #1433466 писал(а):
slavav в сообщении #1433459 писал(а):
Отделите выделение/удаление массивов от основных вычислений

я это уже делал - и результат оказался плачевным,уж не знаю почему, но так оно получилось, вернул всё обратно, как было раньше
Вы упустили возможность выяснить где ошибка.
Andrey_Kireew в сообщении #1433466 писал(а):

Dmitriy40, забыл уточнить - зависание происходит уже при выходе из потоков, время вычислений уже успевает отобразиться на экране. Где там вообще может что зависнуть, не знаете?
На освобождении массивов. Скорее всего вы затираете заголовки объектов в куче.

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение05.01.2020, 00:52 
Andrey_Kireew в сообщении #1433455 писал(а):
Ну и static опять же непонятно ... Может к этой структуре какие то особые требования есть?
Не знаю таких, существования на всё время использования достаточно, у Вас оно выполняется.
Andrey_Kireew в сообщении #1433455 писал(а):
Но вот если выделить в основном потоке и передать указатели через структуру (вроде как тот же динамический массив, а предаётся только его адрес) некоторые потоки завершаются быстро, а некоторые долго пыхтят.
Ищите ошибку с индексами/указателями: основному коду вычислений должно быть совершенно фиолетово откуда взялся указатель на массив, из new или из структуры. Вполне вероятно что где-то перепутали индексы или указатели. А на правильность итогового результата оно может и не повлиять — если вычисленная с ошибкой величина меньше найденного ранее максимума и на выход не попадает, зато время очень даже занимает.
Присоединяюсь к совету отказаться от указателей в пользу индексов и расставить везде ассерты с проверкой индексов (да и указателей) на выход за массивы.
Andrey_Kireew в сообщении #1433466 писал(а):
забыл уточнить - зависание происходит уже при выходе из потоков, время вычислений уже успевает отобразиться на экране. Где там вообще может что зависнуть, не знаете?
Вообще прелестно, виснет конец основного потока ... А там лишь CloseHandle и delete ... Хотя, вот что тут for (int ii=0; ii<L; ii++) *(ind+ii)=double((a[id].index)[ii]+1); за переменная ind мне непонятно. Почему бы и не зависнуть ... :mrgreen: Как это вообще скомпилилось то ... :facepalm:

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение05.01.2020, 01:29 
slavav в сообщении #1433469 писал(а):
Я говорил об изменении кода программы так, чтобы в случае обращения вне границ массива программа немедленно сообщала об ошибке

Если Вы об этом, то на мой взгляд проще запретить выход за эти границы. По опыту знаю, что замена while() на for() в этом сильно помогает. Есть и другие приёмы. В общем я понял, где нужно - сделаю вставки.

slavav в сообщении #1433469 писал(а):
Вы упустили возможность выяснить где ошибка.

Это да, упустил. Жаль конечно, но и времени на выяснение тоже жаль. Пусть будет так как есть.

slavav в сообщении #1433469 писал(а):
На освобождении массивов. Скорее всего вы затираете заголовки объектов в куче

можно ли это как то исправить?

Dmitriy40 в сообщении #1433470 писал(а):
за переменная ind мне непонятно. Почему бы и не зависнуть ... :mrgreen: Как это вообще скомпилилось то ... :facepalm:

эта никакая не переменная, а указатель. и ничего смешного

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение05.01.2020, 02:16 
Andrey_Kireew в сообщении #1433474 писал(а):
slavav в сообщении #1433469 писал(а):
На освобождении массивов. Скорее всего вы затираете заголовки объектов в куче
можно ли это как то исправить?
Не пишите за пределами массивов.

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение05.01.2020, 02:25 
Аватара пользователя
Andrey_Kireew, замените все сырые массивы на vector, и обращайтесь к нему через at - может помочь (еще может помочь использование address sanitizer, но в MSVC 2010 его явно нет).

Еще проверьте, что у вас потоки реально создаются (_beginthreadex возвращает не 0) - черт его знает, что следующие функции делают с некорректными хандлерами.
И попробуйте прямо в функции select писать, когда она запустилась и с какими параметрами, и когда завершилась.

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение05.01.2020, 03:38 
Andrey_Kireew в сообщении #1433474 писал(а):
Dmitriy40 в сообщении #1433470 писал(а):
за переменная ind мне непонятно. Почему бы и не зависнуть ... :mrgreen: Как это вообще скомпилилось то ... :facepalm:
эта никакая не переменная, а указатель. и ничего смешного
Лучше бы честно сказали что случайно удалили при сокращении кода его объявление и инициализацию — я бы и не считал тогда его использование ошибкой.

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение05.01.2020, 07:33 
В последнем листинге от Andrey_Kireew ошибка:
Код:
int i0=((DATA *)a)->ini;

Переменная init по ошибке заменена на ini.

 
 
 
 Re: Распараллеливание программы (ядра/потоки)
Сообщение05.01.2020, 12:58 
mihaild в сообщении #1433478 писал(а):
Еще проверьте, что у вас потоки реально создаются (_beginthreadex возвращает не 0) - черт его знает

Спасибо mihaild!!! Похоже в этом и был весь корень "зла".

Сделал так:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
..........
unsigned int start_time =  GetTickCount(); //clock(); // начальное время

HANDLE *Th=new HANDLE[numCPU];
for (int j=0;j<numCPU;j++)
  do
  Th[j]=(HANDLE)_beginthreadex(NULL, 0, &select, (void *) &a[j], 0, NULL);
  while (Th[j]==0);

WaitForMultipleObjects(numCPU, Th, TRUE, INFINITE);

unsigned int dT = GetTickCount()-start_time; // конечное время;clock()
printf("T=%d ms \n",dT);
..........
 


Вот время выполнения кода в 8 потоков на 4-х ядрах с включённым HiperThread:
    T=87,14 sec
    T=87,11 sec
    T=87,28 sec
    T=87,13 sec
    T=86,98 sec
    T=87,20 sec

Мало того, что это самое быстрое время из того, что было раньше, оно ещё и весьма стабильное, т.е. такое, как и должно быть по мнению Dmitriy40.

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

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

 
 
 [ Сообщений: 210 ]  На страницу Пред.  1 ... 3, 4, 5, 6, 7, 8, 9 ... 14  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group