реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> VC2015 и VC2010. Файл вырастает в 3,5раза
jcxz
сообщение Aug 1 2018, 08:57
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(DASM @ Jul 31 2018, 22:14) *
это не оптимизация. Можно код исходный?

Оптимизация wink.gif ....так как с выключением оной там становится ещё страшнее. smile3046.gif
Исходный? Я же листинг привёл с включением исходных строк.

Цитата(jcxz @ Jul 31 2018, 15:07) *
Не знаю. Надо будет дома на VS2005 проверить. На работе VS2005 уже не ставится на win64 sad.gif((

Проверить дома пока не получается - дома +30 и выше - в такой жаре и комп включать не охота. 05.gif
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 1 2018, 09:27
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



определения типов , входящих в эти строки можно? что то додумывать не хочется
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2018, 09:41
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(DASM @ Aug 1 2018, 12:27) *
определения типов , входящих в эти строки можно? что то додумывать не хочется

Код
struct OscRaw {
  uint chainN;                //кол-во не-NULL указателей chain
  uint nv0, ixf0, nvf0;       //соответственно chain[0].nv, chain[0].ixf и chain[0].fmt[ixf].n на момент защёлкивания Get()
  FILETIME timestamp;         //временная метка последних принятых данных
  char timestampOk;           //!=0 - timestamp валидно
  uint oscsrcNV[OSCSRC_n];    //кол-во векторов по каждому источнику осц. непрерывным участком от самого нового вектора до ближайшего разрыва по данному источнику
  HCOsc *chain[OSC_BRING_N];  //массив блоков данных векторов осц. (каждый имеет заголовок HCOsc)
  TIPCALL OscRaw() { ZeroMemory(this, sizeof(*this)); }
  TIPCALL OscRaw(OscRaw const &src) { ZeroMemory(this, sizeof(*this)); *this = src; }
  TIPCALL ~OscRaw() { Destroy(); }
  void TIPCALL Get();
  void TIPCALL Destroy();
  OscRaw & operator =(OscRaw const &);
};
struct HCOsc {
  long volatile use; //кол-во пользователей данного элемента (кол-во link-ов на него)
  uint volatile nv;  //кол-во векторов в данном элементе
  uint ixf;          //индекс последнего записанного элемента fmt (кол-во_записанных_элементов_fmt - 1)
  struct Format {
    u64 map;         //бит-карта источников осц. для n векторов
    uint n;          //кол-во векторов осц. которые соответствуют карте map
    uint TIPCALL GetVktOffs(uint) const;
  } fmt[64];         //список описателей формата векторов в данном элементе HCOsc
  void TIPCALL Delete() { if (!InterlockedDecrement(&use)) delete this; }
};

А приведённый кусок кода - это участок результата компиляции OscRaw::Get():
Код
void TIPCALL OscRaw::Get()
{
  HCOsc *p, **pb = &chain[0];
...
  if (chainN = n) {
    nv0 = (p = chain[0])->nv;
    nvf0 = p->fmt[ixf0 = p->ixf].n;
  }
  timestamp = ::timestamp;
  timestampOk = ::timestampOk;
  memcpy(oscsrcNV, (void *)&::oscsrcNV[0], sizeof(oscsrcNV));
  LeaveCriticalSection(&csb);
}

Как видите - volatile в данных местах нету.

PS: Копирование в промежуточную переменную p = chain[0] это уже я позже добавил. В таком варианте эти лишние чтения указателя уже пропадают.
Т.е. - компилятор почему-то сам не догадывается так сделать (сохранить chain[0] в регистре), но если ему явно указать на это, поместив указатель в отдельную переменную (p), то p он уже оптимизирует в регистр.
По идее - раз массив chain указан без volatile, то значит не имеет side effects, а значит его члены можно перемещать куда угодно и создавать сколько угодно копий.
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 1 2018, 10:13
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



if (chainN = n) не компилится, это не член OscRaw
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2018, 10:16
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(DASM @ Aug 1 2018, 13:13) *
if (chainN = n) не компилится, это не член OscRaw

В смысле? Посмотрите на первую строчку объявления OscRaw.
Думаете я листинг сам руками рисовал, чтобы всех в заблуждение ввести? biggrin.gif
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 1 2018, 10:18
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



где там n?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2018, 10:22
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(DASM @ Aug 1 2018, 13:18) *
где там n?

"..." ни о чём не говорит? Подумайте. Естественно не относящийся к теме код поскипан.
n вычисляется кодом ранее. Потом заносится в chainN. Могли бы догадаться.
Да и зачем вам оно?
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 1 2018, 10:24
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



ну а вдруг. Догадаться не могу, тупой я.
Go to the top of the page
 
+Quote Post
XVR
сообщение Aug 1 2018, 11:33
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(jcxz @ Aug 1 2018, 12:41) *
PS: Копирование в промежуточную переменную p = chain[0] это уже я позже добавил. В таком варианте эти лишние чтения указателя уже пропадают.
Т.е. - компилятор почему-то сам не догадывается так сделать (сохранить chain[0] в регистре)
Он не может. У вас там присваивания в поля структуры OscRaw (nv0 и nvf0). Для компилятора это запись в память. Видимо анализ указателей у VC хромает (или выключен), и он считает, что эта запись потенциально может попасть в любой глобальный объект (ч том числе и в те, к которым обращаются через указатель). Поэтому содержимое chain может измениться (с точки зрения компилятора).
Цитата
но если ему явно указать на это, поместив указатель в отдельную переменную (p), то p он уже оптимизирует в регистр.
тут вы взяли отвественность на себя, явно переместив значение в локальную переменную. Для неё pointer анализ говорит, что она ни с какими указателями не пересекается.
Цитата
По идее - раз массив chain указан без volatile, то значит не имеет side effects, а значит его члены можно перемещать куда угодно и создавать сколько угодно копий.
Нет. В массив могут записать 'сбоку' (не через указатель на него).
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2018, 12:12
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(XVR @ Aug 1 2018, 14:33) *
Нет. В массив могут записать 'сбоку' (не через указатель на него).

Мне кажется странными если оптимизатор делает такие предположения.
Вставил этот код в IAR, вот что он выдал:
Код
     86              nv0 = chain[0]->nv;
   \   00000004   0x6A41             LDR      R1,[R0, #+36];1-е чтение chain[0]
   \   00000006   0x684A             LDR      R2,[R1, #+4] ;чтение chain[0]->nv
   \   00000008   0x6042             STR      R2,[R0, #+4] ;запись nv0
     87              nvf0 = chain[0]->fmt[ixf0 = chain[0]->ixf].n;
   \   0000000A   0x6889             LDR      R1,[R1, #+8] ;чтение chain[0]->ixf
   \   0000000C   0x6A42             LDR      R2,[R0, #+36];3-е чтение chain[0]
   \   0000000E   0x6081             STR      R1,[R0, #+8] ;запись ixf0
   \   00000010   0xEB02 0x1101      ADD      R1,R2,R1, LSL #+4
   \   00000014   0x6989             LDR      R1,[R1, #+24] ;чтение chain[0]->fmt[ixf0].n
   \   00000016   0x60C1             STR      R1,[R0, #+12] ;запись nvf0

Как видно - IAR так не предполагает: он выкинул 2-е чтение chain[0] из памяти, использовав старое значение в регистре, хоть перед этим и была запись в память.
3-е чтение он правда оставил, хотя мог бы тоже использовать если-б не разрушил его перед тем.
Более того - он и 3-е чтение расположил до записи ixf0, хотя если следовать Вашей логике не должен был этого делать. Так что на возможности затирания записями ему наплевать, так как: side effects - это забота программиста.
Go to the top of the page
 
+Quote Post
XVR
сообщение Aug 1 2018, 15:43
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(jcxz @ Aug 1 2018, 15:12) *
Более того - он и 3-е чтение расположил до записи ixf0, хотя если следовать Вашей логике не должен был этого делать. Так что на возможности затирания записями ему наплевать
Он не прав sm.gif

Цитата
, так как: side effects - это забота программиста.
Это не так. Если в программе нет того, что называется undefined behavior, то разница в её поведении на разных уровнях оптимизации - это ошибка компилятора.

Другое дело, что оптимизатор в VC всегда не являлся сильным местом компилятора. Нормальный оптимизатор в состоянии разобраться (или предположить, если ему пользователь скажет), могут указатели пересекаться или нет.
Попробуйте собрать программу с опцией 'Full program optimization' (или как она там называется). Ещё можно попробовать сделать поля в nv0 и nvf0 другого размера (была такая опция - ansi alias. Она предполагала, что типизированные указатели на память не могут пересекаться, если они указывают на типы, несовместимые по прямому присваиванию. Не знаю, есть ли оно в VC, но всё может быть)

Go to the top of the page
 
+Quote Post
Gate
сообщение Aug 1 2018, 15:53
Сообщение #27


Знающий
****

Группа: Свой
Сообщений: 859
Регистрация: 7-04-05
Из: Санкт-Петербург
Пользователь №: 3 943



Мне кажется, здесь объяснено поведение компилятора https://m.habr.com/post/114117/


--------------------
"Человек - это существо, которое охотнее всего рассуждает о том, в чем меньше всего разбирается." (с) С.Лем
Go to the top of the page
 
+Quote Post
XVR
сообщение Aug 1 2018, 15:57
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Используйте спецификатор __restrict
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 1 2018, 16:03
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(XVR @ Aug 1 2018, 18:43) *
Это не так. Если в программе нет того, что называется undefined behavior, то разница в её поведении на разных уровнях оптимизации - это ошибка компилятора.

Программа и не ведёт себя по-разному на разных уровнях. Багов нет. Есть неоптимальность.

Цитата(XVR @ Aug 1 2018, 18:43) *
Попробуйте собрать программу с опцией 'Full program optimization' (или как она там называется).

У меня и стоит максимальная оптимизация какая только возможно.

PS: Ладно - интерес был скорее академический. Проблем со скоростью/размером нет.
Go to the top of the page
 
+Quote Post
DASM
сообщение Aug 1 2018, 16:13
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Не не, сливаться не стоит. О restrict точно вспомнили, может попробуете с ним?
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th April 2024 - 19:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01523 секунд с 7
ELECTRONIX ©2004-2016