Вопросы по С/С++ (СИ)
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Ну так и делайте... переменную индекса со смещением задавайте и гоняйте по кругу...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
Re: Вопросы по С/С++ (СИ)
[uquote="Apparatchik",url="/forum/viewtopic.php?p=3265930#p3265930"]Я Вашу мысль понял, но там есче нужно после сдвига сделать вот это[/uquote]
Разбейте массив current[SIZE] на две части current[2][SIZE/2], заведите доп. переменную индекса i1 и
после каждой итерации меняйте части массива местами: i1 ^= 1;
Тогда не надо будет ничего "двигать".
Добавлено after 4 minutes 1 second:
[uquote="ARV",url="/forum/viewtopic.php?p=3265921#p3265921"]if(++index_I >= 400) index_I = 0;[/uquote]
Иногда лучше сделать memcpy() чем в цикле на каждой итерации делать такое. Лучше по скорости работы.
Автору нужна скорость, а такое управление индексом добавит кучу лишних тактов в цикл. Много больше чем memcpy() на больших выровненных массивах.
Для скорости будет лучше сделать memcpy().
А если ещё и 16-битные значения в массивах всё-таки знаковые или беззнаковые, но в диапазоне 0...32767 и работает на Cortex-M4 или выше, то круче будет:
И подровнять расположение массивов на границу 32 бит.
Да и если, как пишет автор, памяти не жалко, то кольцевые массивы можно кратно увеличить уменьшив также кратно количество вызовов memcpy().
Ну или организовать данные в массивах как я выше описал.
Разбейте массив current[SIZE] на две части current[2][SIZE/2], заведите доп. переменную индекса i1 и
после каждой итерации меняйте части массива местами: i1 ^= 1;
Тогда не надо будет ничего "двигать".
Добавлено after 4 minutes 1 second:
[uquote="ARV",url="/forum/viewtopic.php?p=3265921#p3265921"]if(++index_I >= 400) index_I = 0;[/uquote]
Иногда лучше сделать memcpy() чем в цикле на каждой итерации делать такое. Лучше по скорости работы.
Автору нужна скорость, а такое управление индексом добавит кучу лишних тактов в цикл. Много больше чем memcpy() на больших выровненных массивах.
Для скорости будет лучше сделать memcpy().
А если ещё и 16-битные значения в массивах всё-таки знаковые или беззнаковые, но в диапазоне 0...32767 и работает на Cortex-M4 или выше, то круче будет:
Код: Выделить всё
int32_t sum = 0;
uint32_t *p1 = &buf_U[0], *p2 = buf_I[SDVIG];
int i = 400 / 2;
do sum = __SMLAD(*p1++, *p2++, sum);
while (--i);Да и если, как пишет автор, памяти не жалко, то кольцевые массивы можно кратно увеличить уменьшив также кратно количество вызовов memcpy().
Ну или организовать данные в массивах как я выше описал.
Последний раз редактировалось jcxz Пт дек 22, 2017 13:24:09, всего редактировалось 2 раза.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
только вы забываете, что у автора обработка в цикле ПОСЛЕ memcpy, т.е. все такты копирования пойдут плюсом к обработке. а управление индексом добавить по 2-3 такта на итерацию ПОЛЕЗНОГО цикла. так что это еще большой вопрос, что окажется быстрее по совокупностиjcxz писал(а):такое управление индексом добавит кучу лишних тактов в цикл. Много больше чем memcpy() на больших выровненных массивах.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
[uquote="ARV",url="/forum/viewtopic.php?p=3266075#p3266075"]
А вы компилировать пробовали, то что предложили? Где там 2-3 такта? Там все 20 будет на итерацию.
Так как используется дополнительные манипуляции с индексом, то компилятор не сможет адресацию через индексы заменить на адресацию через указатели, а это добавит кучу команд вычисления адресов операций чтения и записи в каждой итерации не считая самой
if(++index_I >= 400) index_I = 0;
которая уже выльется как минимум в 4 команды. И это хорошо если компилятор использует операцию условного выполнения ITxxx, а если нет то поставит условный переход - это будет ещё хуже.
Без этого компилятор заменит все ваши индексные операции с массивами на операции с указателями и на каждой итерации для чтения будет использовать только по две команды LDRH Rx, [Rx], #2.
Если имеется if(++index_I >= 400) index_I = 0; то он не сможет использовать указатели вычисленные перед началом цикла.
Кроме того данные у автора 16-битные, а memcpy() внутри оптимизирована и на больших массивах, выровненных на границу 32бит, будет копировать по 8 шт. 32-битных слов за итерацию, т.е. - будет тратить всего ~ 2 такта на копирование каждой пары значений.
А если ещё как я писал, кратно увеличить размеры массивов, то во столько же крат можно уменьшить количество вызовов memcpy().
только вы забываете, что у автора обработка в цикле ПОСЛЕ memcpy, т.е. все такты копирования пойдут плюсом к обработке. а управление индексом добавить по 2-3 такта на итерацию ПОЛЕЗНОГО цикла. так что это еще большой вопрос, что окажется быстрее по совокупности[/uquote]jcxz писал(а):такое управление индексом добавит кучу лишних тактов в цикл. Много больше чем memcpy() на больших выровненных массивах.
А вы компилировать пробовали, то что предложили? Где там 2-3 такта? Там все 20 будет на итерацию.
Так как используется дополнительные манипуляции с индексом, то компилятор не сможет адресацию через индексы заменить на адресацию через указатели, а это добавит кучу команд вычисления адресов операций чтения и записи в каждой итерации не считая самой
if(++index_I >= 400) index_I = 0;
которая уже выльется как минимум в 4 команды. И это хорошо если компилятор использует операцию условного выполнения ITxxx, а если нет то поставит условный переход - это будет ещё хуже.
Без этого компилятор заменит все ваши индексные операции с массивами на операции с указателями и на каждой итерации для чтения будет использовать только по две команды LDRH Rx, [Rx], #2.
Если имеется if(++index_I >= 400) index_I = 0; то он не сможет использовать указатели вычисленные перед началом цикла.
Кроме того данные у автора 16-битные, а memcpy() внутри оптимизирована и на больших массивах, выровненных на границу 32бит, будет копировать по 8 шт. 32-битных слов за итерацию, т.е. - будет тратить всего ~ 2 такта на копирование каждой пары значений.
А если ещё как я писал, кратно увеличить размеры массивов, то во столько же крат можно уменьшить количество вызовов memcpy().
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
нет, конечно.jcxz писал(а):А вы компилировать пробовали, то что предложили?
собственно, с этого я и начал, так что не надо мне об этом рассказывать.jcxz писал(а):Кроме того данные у автора 16-битные, а memcpy() внутри оптимизирована и на больших массивах, выровненных на границу 32бит, будет копировать по 8 шт. 32-битных слов за итерацию, т.е. - будет тратить всего ~ 2 такта на копирование каждой пары значений.
а все наши с вами рассуждения могут ничего не стоить, если компилятор хорошо оптимизирует.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Реклама
- Apparatchik
- Держит паяльник хвостом
- Сообщения: 908
- Зарегистрирован: Вс май 23, 2010 13:55:42
- Откуда: Украина, Александрия
Re: Вопросы по С/С++ (СИ)
[uquote="jcxz",url="/forum/viewtopic.php?p=3266089#p3266089"]А если ещё как я писал, кратно увеличить размеры массивов, то во столько же крат можно уменьшить количество вызовов memcpy().[/uquote]
Этого сделать нельзя так, как в зависимости от частоты количество измерений на период разное и в идиале составляет 400шт, но постоянно плавает.
Этого сделать нельзя так, как в зависимости от частоты количество измерений на период разное и в идиале составляет 400шт, но постоянно плавает.
«И всё-таки она вертится!»
Re: Вопросы по С/С++ (СИ)
[uquote="ARV",url="/forum/viewtopic.php?p=3266096#p3266096"]а все наши с вами рассуждения могут ничего не стоить, если компилятор хорошо оптимизирует.[/uquote]
По-любому лучшая оптимизация индексных обращений к массивам - замена и на обращения через указатели, вычисленные перед циклом.
А в теле цикла - работа с этими указателями командами с автоинкрементом.
Но если есть модификация индексов внутри цикла, то заменить на указатели компилятор не сможет. А значит на каждой итерации будет заново считать исполнительные адреса для каждого операнда.
Вот во что компилируется приведённый мной код:
Быстрее почти некуда:
Всего 6 тактов на каждые 2 пары операндов (не считая условного перехода).
Добавлено after 4 minutes 9 seconds:
[uquote="Apparatchik",url="/forum/viewtopic.php?p=3266102#p3266102"]Этого сделать нельзя так, как в зависимости от частоты количество измерений на период разное и в идиале составляет 400шт, но постоянно плавает.[/uquote]
Ну и что?
Создаёте массив скажем примерно в 10 раз больше = 4000 значений. А это значит, что если в кольцевой буфер размером 400 значений каждый раз добавлять по примерно 400 новых значений, то значит примерно на одно добавление будет примерно одно пересечение границы. А если размер == 4000 значений, то значит пересечение будет примерно на каждое 10-е добавление.
А делать memcpy() нужно только при пересечении границы массива.
Так что без разницы - что фиксированное кол-во добавлять, что переменное.
По-любому лучшая оптимизация индексных обращений к массивам - замена и на обращения через указатели, вычисленные перед циклом.
А в теле цикла - работа с этими указателями командами с автоинкрементом.
Но если есть модификация индексов внутри цикла, то заменить на указатели компилятор не сможет. А значит на каждой итерации будет заново считать исполнительные адреса для каждого операнда.
Вот во что компилируется приведённый мной код:
Код: Выделить всё
u32 *p1 = &d.sh.bp[0], sum = 0;
enum {SDVIG = 100};
int i = 400 / 2;
do {
sum = __SMLAD(p1[0], p1[SDVIG], sum);
p1++;
} while (--i);
Код: Выделить всё
MOVS R0,#+200
??DtePwm_0:
LDR R3,[R2, #+400]
LDR R6,[R2], #+4
SUBS R0,R0,#+1
SMLAD R1,R6,R3,R1
BNE.N ??DtePwm_0Добавлено after 4 minutes 9 seconds:
[uquote="Apparatchik",url="/forum/viewtopic.php?p=3266102#p3266102"]Этого сделать нельзя так, как в зависимости от частоты количество измерений на период разное и в идиале составляет 400шт, но постоянно плавает.[/uquote]
Ну и что?
Создаёте массив скажем примерно в 10 раз больше = 4000 значений. А это значит, что если в кольцевой буфер размером 400 значений каждый раз добавлять по примерно 400 новых значений, то значит примерно на одно добавление будет примерно одно пересечение границы. А если размер == 4000 значений, то значит пересечение будет примерно на каждое 10-е добавление.
А делать memcpy() нужно только при пересечении границы массива.
Так что без разницы - что фиксированное кол-во добавлять, что переменное.
- КРАМ
- Друг Кота
- Сообщения: 25359
- Зарегистрирован: Чт янв 10, 2008 22:01:02
- Откуда: Московская область, Фрязино
Re: Вопросы по С/С++ (СИ)
[uquote="Apparatchik",url="/forum/viewtopic.php?p=3265900#p3265900"]В общем зачем эти подробности? Я же сказал что уже работает и просто спросил может можно сдвинуть как то быстрее. Нет так нет.[/uquote]
Ну хотя бы затем, что порой не слишком, ээээ, оптимальный метод измерений дает раздутые никчемные расчеты. А порой и избыточные исходные данные.
Ну хотя бы затем, что порой не слишком, ээээ, оптимальный метод измерений дает раздутые никчемные расчеты. А порой и избыточные исходные данные.
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Предположим есть некая переменная v16, она задействована в функциях различных прерываний. Также эта переменная используется для связи с главным циклом программы.
По уму она должна быть объявлена следующим образом:
Такая запись исключает какую-либо оптимизацию над этой переменной.
Прерывания у меня не вложенные, имеют одинаковый приоритет и не могут прерывать друг друга.
Я подумал, а нельзя ли включить оптимизацию над этой переменной в обработчиках прерываний и выключить в главном цикле. Всё это затевается чтобы немного сократить время выполнения обработчиков.
Решил написать примерно так:
Кто что думает на этот счёт?
По уму она должна быть объявлена следующим образом:
Код: Выделить всё
volatile uint16_t v16;Прерывания у меня не вложенные, имеют одинаковый приоритет и не могут прерывать друг друга.
Я подумал, а нельзя ли включить оптимизацию над этой переменной в обработчиках прерываний и выключить в главном цикле. Всё это затевается чтобы немного сократить время выполнения обработчиков.
Решил написать примерно так:
Код: Выделить всё
#define ACCESS_VOLATILE_U16(x) (*((volatile uint16_t*) &x))
uint16_t v16;
void irq_handler1( void ) // прерывания
{
v16 = 1;
}
void irq_handler2( void )
{
v16 = 2;
}
main()
{
ACCESS_VOLATILE_U16( v16 ) = 0;
while(1)
{
abc = ACCESS_VOLATILE_U16( v16 );
};
}
Re: Вопросы по С/С++ (СИ)
имхо довольно бессмысленное занятие. Какие, по-вашему, оптимизации могут ускорить здесь выполнение обработчиков, при этом сохранив корректность?
sdcc, к примеру, совсем выкидывает из цикла строку abc = ACCESS_VOLATILE_U16( v16 ), если v16 не объявлена как volatile с самого начала.
sdcc, к примеру, совсем выкидывает из цикла строку abc = ACCESS_VOLATILE_U16( v16 ), если v16 не объявлена как volatile с самого начала.
-
uk8amk
- Поставщик валерьянки для Кота
- Сообщения: 2222
- Зарегистрирован: Вт ноя 27, 2007 11:32:06
- Откуда: Tashkent
Re: Вопросы по С/С++ (СИ)
Разумеется данный кусок кода был придуман и выложен только лишь для примера.
Код реального проекта сложнее и запутаннее.
Он реализует через прерывания определение состояния, вычисление угловой позиции механизма и формирование управляющих воздействий.
В главном цикле содержится "медленный" алгоритм, который пропускает полученные данные через модель и корректирует управление. Также осуществляется связь с компьютером.
Данные о состоянии механизма записаны в структуре примерно следующего вида:
Например переменная состояния state_machine используется как в конечном автомате в прерываниях, так и для управления из главного цикла.
Переменная rev_period_latch используется в прерываниях для вычисления ускорений, угловых и временных моментов управления. Она же используется в главном цикле для корректировки управления.
Такой доступ к данным получается не очень оптимальным. Я пока придумал 2 варианта.
Вариант 1.
Все поля структур какие надо объявляются как volatile.
Внутри функций они копируются во временные переменные, которым разрешена оптимизация. На выходе копируются обратно.
Например:
Вариант 2.
В структуре ENGINE_PARAMS все данные не volatile и из функций прерываний к ним идёт самый обычный доступ.
Но объявляется дополнительный указатель
через который получается volatile доступ к членам структуры из главного цикла:
Вариант 2 похож на тот, о котором говорил в предыдущем сообщении.
Кто как решает подобные вопросы? Просто объявлять нужные поля структуры как volatile и не заморачиваться?
Да, компилятор ARMCC, но это наверно не имеет значения т.к. везде должно быть одинково.
Ещё. Есть специализированные DSP процессоры, в которых моя задача решена на аппаратном уровне. Но мне они пока недоступны.
Код реального проекта сложнее и запутаннее.
Он реализует через прерывания определение состояния, вычисление угловой позиции механизма и формирование управляющих воздействий.
В главном цикле содержится "медленный" алгоритм, который пропускает полученные данные через модель и корректирует управление. Также осуществляется связь с компьютером.
Данные о состоянии механизма записаны в структуре примерно следующего вида:
Код: Выделить всё
typedef struct{
volatile
uint8_t state_machine; // машина состояний
int16_t angle_cnt; // текущая угловая позиция
volatile
uint8_t event; // события
uint32_t rev_period_cnt; // счётчик периода оборота диска энкодера
volatile
uint32_t rev_period_latch; // период последнего полного оборота
uint32_t rev_period_pred; // предсказание периода следующего оборота
// и ещё десяток параметров
}ENGINE_PARAMS;
ENGINE_PARAMS engine_data;Переменная rev_period_latch используется в прерываниях для вычисления ускорений, угловых и временных моментов управления. Она же используется в главном цикле для корректировки управления.
Такой доступ к данным получается не очень оптимальным. Я пока придумал 2 варианта.
Вариант 1.
Все поля структур какие надо объявляются как volatile.
Внутри функций они копируются во временные переменные, которым разрешена оптимизация. На выходе копируются обратно.
Например:
Код: Выделить всё
void proc_engine_state( void )
{
uint8_t sm = engine_data.state_machine;
// делать что-то с переменной sm
engine_data.state_machine = sm;
}В структуре ENGINE_PARAMS все данные не volatile и из функций прерываний к ним идёт самый обычный доступ.
Код: Выделить всё
typedef struct{
uint8_t state_machine; // машина состояний
int16_t angle_cnt; // текущая угловая позиция
uint8_t event; // события
uint32_t rev_period_cnt; // счётчик периода оборота диска энкодера
uint32_t rev_period_latch; // период последнего полного оборота
uint32_t rev_period_pred; // предсказание периода следующего оборота
// и ещё десяток параметров
}ENGINE_PARAMS; Код: Выделить всё
volatile ENGINE_PARAMS *p_engine_data;Код: Выделить всё
ENGINE_PARAMS engine_data; // вот это используется только прерываниями
volatile ENGINE_PARAMS *p_engine_data;// а это для главного цикла
main()
{
p_engine_data->state_machine = STOP; // иниц значений
p_engine_data->angle_cnt = 0;
p_engine_data->rev_period_cnt = 0;
while(1)
{
if( p_engine_data->state_machine == WORK )
{
putsf("ENGINE WORK");
}else
{
putsf("ENGINE STOP");
}
if( p_engine_data->event == ERROR )
{
reinit_engine();
putsf("ERROR");
}
}
}Кто как решает подобные вопросы? Просто объявлять нужные поля структуры как volatile и не заморачиваться?
Да, компилятор ARMCC, но это наверно не имеет значения т.к. везде должно быть одинково.
Ещё. Есть специализированные DSP процессоры, в которых моя задача решена на аппаратном уровне. Но мне они пока недоступны.
- Oxford
- Опытный кот
- Сообщения: 819
- Зарегистрирован: Вт окт 23, 2012 13:17:25
- Откуда: Прокопьевск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Не знаю что ты там делаешь и что хочешь, но методом вангования предложу способ оптимизации скорости кода, если хочешь ускорить работу с некоторой переменной обьяви ее с директивой register компилятор закрепит ее в регистре общего назначения это ускорит работу кода. Только смотри регистры не резиновые )))
Инженер R@D
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Telegram чат: https://t.me/radiowolf или в поиске приложения @radiowolf. Личка:@cncoxford
Re: Вопросы по С/С++ (СИ)
[uquote="uk8amk",url="/forum/viewtopic.php?p=3269085#p3269085"]Разумеется данный кусок кода был придуман и выложен только лишь для примера.
Код реального проекта сложнее и запутаннее.[/uquote]
приведите реальный код
[uquote="uk8amk",url="/forum/viewtopic.php?p=3269085#p3269085"]Он реализует через прерывания определение состояния, вычисление угловой позиции механизма и формирование управляющих воздействий.[/uquote]
он этим прямо в прерывании занимается? не то чтобы это было хорошей идеей.
[uquote="uk8amk",url="/forum/viewtopic.php?p=3269085#p3269085"]В главном цикле содержится "медленный" алгоритм, который пропускает полученные данные через модель и корректирует управление. Также осуществляется связь с компьютером.[/uquote]
можно воткнуть какйюнить RTOS, умеющую в кванты времени и приоритеты тредов, в прерывании выставлять флаги готовности к работе приоритетных задач, "медленный алгоритм" задать низкоприоритетным.
[uquote="uk8amk",url="/forum/viewtopic.php?p=3269085#p3269085"]Такой доступ к данным получается не очень оптимальным. Я пока придумал 2 варианта.[/uquote]
первый вариант более очевиден и имхо предпочтителен
[uquote="uk8amk",url="/forum/viewtopic.php?p=3269085#p3269085"]Да, компилятор ARMCC, но это наверно не имеет значения т.к. везде должно быть одинково.[/uquote]
стандарт ничего особо не говорит про такие финты ушами, кроме как UB при касте volatile к не-volatile. В предыдущем минимальном примере gcc и clang оставляют тело цикла, sdcc - выбрасывает
Код реального проекта сложнее и запутаннее.[/uquote]
приведите реальный код
[uquote="uk8amk",url="/forum/viewtopic.php?p=3269085#p3269085"]Он реализует через прерывания определение состояния, вычисление угловой позиции механизма и формирование управляющих воздействий.[/uquote]
он этим прямо в прерывании занимается? не то чтобы это было хорошей идеей.
[uquote="uk8amk",url="/forum/viewtopic.php?p=3269085#p3269085"]В главном цикле содержится "медленный" алгоритм, который пропускает полученные данные через модель и корректирует управление. Также осуществляется связь с компьютером.[/uquote]
можно воткнуть какйюнить RTOS, умеющую в кванты времени и приоритеты тредов, в прерывании выставлять флаги готовности к работе приоритетных задач, "медленный алгоритм" задать низкоприоритетным.
[uquote="uk8amk",url="/forum/viewtopic.php?p=3269085#p3269085"]Такой доступ к данным получается не очень оптимальным. Я пока придумал 2 варианта.[/uquote]
первый вариант более очевиден и имхо предпочтителен
[uquote="uk8amk",url="/forum/viewtopic.php?p=3269085#p3269085"]Да, компилятор ARMCC, но это наверно не имеет значения т.к. везде должно быть одинково.[/uquote]
стандарт ничего особо не говорит про такие финты ушами, кроме как UB при касте volatile к не-volatile. В предыдущем минимальном примере gcc и clang оставляют тело цикла, sdcc - выбрасывает
или нет. Компилятор в общем случае не обязан этого делать:Oxford писал(а):если хочешь ускорить работу с некоторой переменной обьяви ее с директивой register компилятор закрепит ее в регистре общего назначения
A declaration of an identifier for an object with storage-class specifier register suggests that access to the object be as fast as possible. The extent to which such suggestions are effective is implementation-defined. The implementation may treat any register declaration simply as an auto declaration.
Re: Вопросы по С/С++ (СИ)
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3269167#p3269167"]или нет. Компилятор в общем случае не обязан этого делать[/uquote]
Этот register компилятор скорее всего проигнорит, т.к. в С++17 код с ним уже даже не компилится, а до этого он долго был depricated и игнорировался, потому учитывая общую кодовую базу компиляторов можно ожидать такое поведение и в С, но в том же gсс есть еще другая форма записи, с привязкой к конкретному регистру, вот тот register точно работает.
Этот register компилятор скорее всего проигнорит, т.к. в С++17 код с ним уже даже не компилится, а до этого он долго был depricated и игнорировался, потому учитывая общую кодовую базу компиляторов можно ожидать такое поведение и в С, но в том же gсс есть еще другая форма записи, с привязкой к конкретному регистру, вот тот register точно работает.
Re: Вопросы по С/С++ (СИ)
[uquote="Reflector",url="/forum/viewtopic.php?p=3269178#p3269178"]Этот register компилятор скорее всего проигнорит, т.к. в С++17 код с ним уже даже не компилится, а до этого он долго был depricated и игнорировался[/uquote]
в C - нет. Та цитата из стандарта (черновика) C11. C++ - другой язык, а не "С с классами"
в C - нет. Та цитата из стандарта (черновика) C11. C++ - другой язык, а не "С с классами"
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
C99 вводит типы данных с быстрым доступом, например, fast_int8_t... по идее компилятор должен подобрать для переменной этого типа самый быстрый способ доступа... т.е. типозависимая какая-то оптимизация должна быть. для ARM родным является 32-битный тип, и очень может быть, именно он окажется самым быстрым... т.к. я никогда не работал с ARM, мне неведомо, как отреагирует на fast_int8_t ваш компилятор... но попробуйте.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3269187#p3269187"]в C - нет. Та цитата из стандарта (черновика) C11. C++ - другой язык, а не "С с классами"
[/uquote]
Разве я сказал, что да? Просто в С++11 register стал depricated, т.к. в большинстве случаев он и так игнорировался, потому такое же поведение можно ожидать и от С. Это хинт, чем продвинутее компилятор, тем меньше в нем необходимости, кроме того использование глобального register привносит ряд ограничений, например, у меня с ним не работает LTO.
Разве я сказал, что да? Просто в С++11 register стал depricated, т.к. в большинстве случаев он и так игнорировался, потому такое же поведение можно ожидать и от С. Это хинт, чем продвинутее компилятор, тем меньше в нем необходимости, кроме того использование глобального register привносит ряд ограничений, например, у меня с ним не работает LTO.
Re: Вопросы по С/С++ (СИ)
[uquote="ARV",url="/forum/viewtopic.php?p=3269218#p3269218"]C99 вводит типы данных с быстрым доступом, например, fast_int8_t... по идее компилятор должен подобрать для переменной этого типа самый быстрый способ доступа...[/uquote]
строго говоря, не способ доступа, а быстрее всего обрабатываемый тип. Довольно вероятно, что компилятор его в конце концов использует и для простого uint8_t.
строго говоря, не способ доступа, а быстрее всего обрабатываемый тип. Довольно вероятно, что компилятор его в конце концов использует и для простого uint8_t.
почему вдруг?Reflector писал(а):потому такое же поведение можно ожидать и от С
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18647
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
ну я хотел донести следующую мысль: если тип должен быстрее всего обрабатываться, то переменная этого типа должна попасть в такую область хранения, которая эту самую быстроту способна обеспечить. например, такая переменная может иметь приоритет перед остальными для хранения в регистре...arkhnchul писал(а):строго говоря, не способ доступа, а быстрее всего обрабатываемый тип
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
[uquote="ARV",url="/forum/viewtopic.php?p=3269218#p3269218"]C99 вводит типы данных с быстрым доступом, например, fast_int8_t... по идее компилятор должен подобрать для переменной этого типа самый быстрый способ доступа... т.е. типозависимая какая-то оптимизация должна быть. для ARM родным является 32-битный тип, и очень может быть, именно он окажется самым быстрым... т.к. я никогда не работал с ARM, мне неведомо, как отреагирует на fast_int8_t ваш компилятор... но попробуйте.[/uquote]
Да, потому лучше эти fast не использовать...
[uquote="arkhnchul",url="/forum/viewtopic.php?p=3269230#p3269230"]почему вдруг?[/uquote]
Потому что смысл register в обоих языках одинаковый, а компилятор по сути один, если не считать чистых сишных компиляторов, которые обычно проще и с поддержкой новых стандартов там похуже, потому для них register может до сих пор что-то значит.
Да, потому лучше эти fast не использовать...
Код: Выделить всё
uint8_t aa = 0;
uint_fast8_t bb = 0;
aa = ~aa; // 0xFF
bb = ~bb; // 0xFFFF'FFFFПотому что смысл register в обоих языках одинаковый, а компилятор по сути один, если не считать чистых сишных компиляторов, которые обычно проще и с поддержкой новых стандартов там похуже, потому для них register может до сих пор что-то значит.


