Вопросы по С/С++ (СИ)
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Мне лень фигнёй заниматься. У тебя, судя по всему, IAR есть. Поставь оптимизацию на скорость и сам листинги смотри какие хочешь.
- Реклама
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Только ты с iar-овских листингов сам и начал.
Ты спросил у кого тут iar установлен? Максимум у двух, может быть у трех. В основном cvavr и avr-gcc.
Для чего надо было приводить такое не равное сравнение? 95 и 37, 42 и 26.
Ты спросил у кого тут iar установлен? Максимум у двух, может быть у трех. В основном cvavr и avr-gcc.
Для чего надо было приводить такое не равное сравнение? 95 и 37, 42 и 26.
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="Dimon456",url="/forum/viewtopic.php?p=4208774#p4208774"]Только ты с iar-овских листингов сам и начал.[/uquote]Я только недавно писал, что IAR для AVR это самый вменяемый инструмент. По листингу вижу, что он сделал то что я ожидал. Почему я не могу им пользоваться?
[uquote="Dimon456",url="/forum/viewtopic.php?p=4208774#p4208774"]Ты спросил у кого тут iar установлен? Максимум у двух, может быть у трех. В основном cvavr и avr-gcc.[/uquote]Мне то до этого какое дело? Пишите в чём хотите.
[uquote="Dimon456",url="/forum/viewtopic.php?p=4208774#p4208774"]Для чего надо было приводить такое не равное сравнение? 95 и 37, 42 и 26.[/uquote]Я приводил сравнение??? Чьи "фирменные" тесты c того и спрашивай. А для начала научись компилятором пользоваться! Никогда не поверю, что GCC в 2 раза медленнее код делает. Попытай ARV, накрайняк, у него вроде проблем никогда не было.
На 8-битке, кстати, можно ещё побыстрей сделать, если не uint32_t использовать, а требуемые 24 бита. На глаз, такта на 4 меньше.
ЗЫ: Кстати, ты там про битовые поля что-то двигал. Попробуй их на ARM, должно быть забористо.
[uquote="Dimon456",url="/forum/viewtopic.php?p=4208774#p4208774"]Ты спросил у кого тут iar установлен? Максимум у двух, может быть у трех. В основном cvavr и avr-gcc.[/uquote]Мне то до этого какое дело? Пишите в чём хотите.
[uquote="Dimon456",url="/forum/viewtopic.php?p=4208774#p4208774"]Для чего надо было приводить такое не равное сравнение? 95 и 37, 42 и 26.[/uquote]Я приводил сравнение??? Чьи "фирменные" тесты c того и спрашивай. А для начала научись компилятором пользоваться! Никогда не поверю, что GCC в 2 раза медленнее код делает. Попытай ARV, накрайняк, у него вроде проблем никогда не было.
На 8-битке, кстати, можно ещё побыстрей сделать, если не uint32_t использовать, а требуемые 24 бита. На глаз, такта на 4 меньше.
Спойлер
Код: Выделить всё
#include "stdint.h"
struct W24
{
uint8_t b1;
uint8_t b2;
uint8_t b3;
};
void foo(volatile W24 *w24, const uint32_t a, bool f)
{
uint16_t tmp = ((a&0xF800)<<1) | (f?(1L<<11):0) | (a&0x700);
w24->b1=(a<<1)>>16; w24->b2=tmp>>8; w24->b3=a;
}
volatile W24 y;
int main()
{
uint32_t a=0;
volatile bool f = true;
while (1)
{
foo(&y,a,f);
a++;
}
}- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
Ну по чему медленнее, то ваше было, а вот 52 и 47, 40 и 36, мое. Не вижу тут в 2 раза, какие-то 11-12 тактов разница, в пользу iar.VladislavS писал(а):что GCC в 2 раза медленнее код делает.
Не думаю что там забористо будет, возможно будет значительно хуже.VladislavS писал(а):Попробуй их на ARM, должно быть забористо.
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
- Реклама
- Сообщения: 1849
- Зарегистрирован: Вс дек 25, 2016 08:34:54
В моем случае я предоставил выбор компилятору, а как он на оптимизировал ... х бы его знал.
Вот на arm stm32f100rbизмерены такты вместе с a++; на реальном чипе.
Вот на arm stm32f100rb
Спойлер
Код: Выделить всё
iar-arm
мой его
51 такт 33 без inline
34 23 inlineбратцы, что я делаю не так?
стоит задача: есть некая фигура, описанная точками на плоскости. надо повернуть эту фигуру относительно другой точки на заданный угол.
поворот точки относительно другой точки описывается такими выражениями:
формулы общеизвестны, однако, вместо поворота получается хрень...
проверяю: то есть тупо поворачиваю точку с определенным шагом, заодно вычисляю длину отрезка, соединяющего центр поворота и повернутую точку - если все хорошо, этот отрезок должен быть одинаковым. но он плавает, как говно в проруби!!!
что я делаю не так?! как надо делать, блин?!
стоит задача: есть некая фигура, описанная точками на плоскости. надо повернуть эту фигуру относительно другой точки на заданный угол.
поворот точки относительно другой точки описывается такими выражениями:
, где (xy) - исходная точка, (x1y1) - результат поворота, а (x0y0) - точка, относительно которой делается поворотx1=(x-x0)∗cos(ϕ)−(y-y0)∗sin(ϕ) + x0
y1=(x-x0)∗sin(ϕ)+(y-y0)∗cos(ϕ) + y0
формулы общеизвестны, однако, вместо поворота получается хрень...
проверяю:
Код: Выделить всё
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#define CENTER 127
void rotate(int *x, int *y, float a){
int tx = *x - CENTER;
int ty = *y - CENTER;
tx = tx * cos(a) - ty * sin(a);
ty = tx * sin(a) + ty * cos(a);
ty += CENTER;
tx += CENTER;
*x=tx; *y = ty;
}
int x, y;
int x0 = 127;
int y0 = 127;
float r;
int main(void) {
// your code goes here
for(uint8_t i = 0; i<60; i++){
x = 127; y = 200;
rotate(&x, &y, i * 3.1415 * 2 / 60);
rotate(&x0, &y0, i * 3.1415 * 2 / 60);
r = sqrt((x0-x)*(x0-x)+(y0-y)*(y0-y));
printf("i=%d, x0=%d, y0=%d, x=%d, y=%d, r=%f\n", i,x0, y0, x, y, r);
}
return 0;
}
вот тут все можно еще раз проверить: https://ideone.com/vdqbQxi=0, x0=127, y0=127, x=127, y=200, r=73.000000
i=1, x0=127, y0=127, x=120, y=198, r=71.344238
i=2, x0=127, y0=127, x=112, y=195, r=69.634758
i=3, x0=127, y0=127, x=105, y=189, r=65.787537
i=4, x0=127, y0=127, x=98, y=181, r=61.294373
i=5, x0=127, y0=127, x=91, y=172, r=57.628117
i=6, x0=127, y0=127, x=85, y=161, r=54.037025
i=7, x0=127, y0=127, x=79, y=149, r=52.801514
i=8, x0=127, y0=127, x=73, y=135, r=54.589375
i=9, x0=127, y0=127, x=68, y=123, r=59.135437
i=10, x0=127, y0=127, x=64, y=109, r=65.520988
i=11, x0=127, y0=127, x=61, y=97, r=72.498276
i=12, x0=127, y0=127, x=58, y=84, r=81.301903
i=13, x0=127, y0=127, x=56, y=73, r=89.202019
i=14, x0=127, y0=127, x=55, y=64, r=95.671310
i=15, x0=127, y0=127, x=55, y=56, r=101.118744
i=16, x0=127, y0=127, x=55, y=48, r=106.887794
i=17, x0=127, y0=127, x=56, y=43, r=109.986366
i=18, x0=127, y0=127, x=58, y=39, r=111.825760
i=19, x0=127, y0=127, x=61, y=38, r=110.801628
i=20, x0=127, y0=127, x=64, y=36, r=110.679718
i=21, x0=127, y0=127, x=68, y=37, r=107.615051
i=22, x0=127, y0=127, x=73, y=39, r=103.247276
i=23, x0=127, y0=127, x=79, y=41, r=98.488579
i=24, x0=127, y0=127, x=85, y=44, r=93.021500
i=25, x0=127, y0=127, x=91, y=46, r=88.639717
i=26, x0=127, y0=127, x=98, y=49, r=83.216583
i=27, x0=127, y0=127, x=105, y=51, r=79.120163
i=28, x0=127, y0=127, x=112, y=53, r=75.504967
i=29, x0=127, y0=127, x=120, y=54, r=73.334846
i=30, x0=127, y0=127, x=127, y=55, r=72.000000
i=31, x0=127, y0=127, x=134, y=54, r=73.334846
i=32, x0=127, y0=127, x=142, y=53, r=75.504967
i=33, x0=127, y0=127, x=149, y=51, r=79.120163
i=34, x0=127, y0=127, x=156, y=49, r=83.216583
i=35, x0=127, y0=127, x=163, y=46, r=88.639717
i=36, x0=127, y0=127, x=169, y=44, r=93.021500
i=37, x0=127, y0=127, x=175, y=41, r=98.488579
i=38, x0=127, y0=127, x=181, y=39, r=103.247276
i=39, x0=127, y0=127, x=186, y=37, r=107.615051
i=40, x0=127, y0=127, x=190, y=36, r=110.679718
i=41, x0=127, y0=127, x=193, y=38, r=110.801628
i=42, x0=127, y0=127, x=196, y=39, r=111.825760
i=43, x0=127, y0=127, x=198, y=43, r=109.986366
i=44, x0=127, y0=127, x=199, y=48, r=106.887794
i=45, x0=127, y0=127, x=199, y=55, r=101.823380
i=46, x0=127, y0=127, x=199, y=64, r=95.671310
i=47, x0=127, y0=127, x=198, y=73, r=89.202019
i=48, x0=127, y0=127, x=196, y=84, r=81.301903
i=49, x0=127, y0=127, x=193, y=97, r=72.498276
i=50, x0=127, y0=127, x=190, y=109, r=65.520988
i=51, x0=127, y0=127, x=186, y=123, r=59.135437
i=52, x0=127, y0=127, x=181, y=135, r=54.589375
i=53, x0=127, y0=127, x=175, y=149, r=52.801514
i=54, x0=127, y0=127, x=169, y=161, r=54.037025
i=55, x0=127, y0=127, x=163, y=172, r=57.628117
i=56, x0=127, y0=127, x=156, y=181, r=61.294373
i=57, x0=127, y0=127, x=149, y=189, r=65.787537
что я делаю не так?! как надо делать, блин?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
какие исходные?! исходная одна, вторая - центр вращения! и как раз тот факт, что при вращении точки не лежат на окружности, меня и шокирует!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
[uquote="ARV",url="/forum/viewtopic.php?p=4213531#p4213531"]... где (xy) - исходная точка, (x1y1) - результат поворота, а (x0y0) - точка, относительно которой делается поворот
...
Может что-то в консерватории подправить? (С) М.Жванецкий
...
[/uquote]i=0, x0=127, y0=127, x=127, y=200, r=73.000000
i=1, x0=127, y0=127, x=120, y=198, r=71.344238
i=2, x0=127, y0=127, x=112, y=195, r=69.634758
...
Может что-то в консерватории подправить? (С) М.Жванецкий
Лучше сделать и жалеть, чем жалеть, что не сделал ...
ну, в консерватории можно подправить... хотя по коду видно же, что сначала x и y присваиваются, а потом передаются в функцию поворота, и уже оттуда возвращаются с новыми (повернутыми) значениями, которые и выводтся
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
У вас меняется tx. Так эти формулы не работают. Надо новые координаты запомнить в отдельных переменных.tx = tx * cos(a) - ty * sin(a);
ty = tx * sin(a) + ty * cos(a);
И день и ночь в пути...
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мои программки: https://github.com/da-nie
Мои публикации: https://habr.com/ru/users/da-nie/posts/
Мои видео: https://www.youtube.com/channel/UCUroi3 ... 52g/videos
Мне, почему-то не совсем нравится:
rotate(&x, &y, i * 3.1415 * 2 / 60); где i - целое, а в функцию должен уйти float результат
Может, для уверенности rotate(&x, &y, float(i * 3.1415 * 2 / 60)); ?
Я однажды запал на такое:
(stepAngle -- float, stepFrame -- int)
причём:
stepAngle = 360/stepFrame;
и stepAngle = float(360/stepFrame);
давало мне совсем не то, что я в столбик посчитал
и только stepAngle = float(360.0/stepFrame) привело к тому, что было нужно.
rotate(&x, &y, i * 3.1415 * 2 / 60); где i - целое, а в функцию должен уйти float результат
Может, для уверенности rotate(&x, &y, float(i * 3.1415 * 2 / 60)); ?
Я однажды запал на такое:
(stepAngle -- float, stepFrame -- int)
причём:
stepAngle = 360/stepFrame;
и stepAngle = float(360/stepFrame);
давало мне совсем не то, что я в столбик посчитал
и только stepAngle = float(360.0/stepFrame) привело к тому, что было нужно.
Лучше сделать и жалеть, чем жалеть, что не сделал ...
да чтоб меня!!! вот, блин, ступил, так ступил!!!da-nie писал(а):У вас меняется tx
спасибо тебе, добрый человек!!!
Добавлено after 4 minutes 40 seconds:
было:
стало:
вот что крест животворящийвзгляд незамыленный делает!
еще раз спасибо, da-nie!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
прошу подсказать, как вычислить время требуемое на то чтобы пройти заданное расстояние по формуле t=√S/(2*a). Проблема в квадратном корне. Но я вычитал, что на третьем кортексе быстрее всего целочисленное привести к флоату, взять корень и снова перевести в целочисленное. Но так как a у меня задаётся как изменение 0.01rpm за 2.5 мс (1r = 220mm)? формула получается такая: √(3000000 * S)/(11 * a). Так вот если я подкоренное выражение считаю целочисленным, то при S=800 (0.8 метра) я уже оказываюсь в переполнении. Как было бы лучше считать. Может эти 3 миллиона уже сделать флоатом и пусть всё считается в плавающей точке?
Пока сделал так. Хотя теряю немного точность - это не принципиально. Функция используется для расчета оптимального маршрута. Главное, чтобы результат был бы всегда повторяем. Но зато вызывается очень много раз.
data.acceleration сейчас порядка 100-200 и distance должна быть до 10 метров (но лучше пусть будет запас еще на порядок).
Пока сделал так. Хотя теряю немного точность - это не принципиально. Функция используется для расчета оптимального маршрута. Главное, чтобы результат был бы всегда повторяем. Но зато вызывается очень много раз.
Код: Выделить всё
int TimeToRunStraight(int distance) { // in milliseconds from millimeters.
return sqrt(3000000/11 * distance/data.acceleration);
}А если sqrt(3000000*x) воспринимать как 1000*sqrt(3*x)? 3000000 - это же константа, как я понял?
P.S. Хотя, точность будет теряться при целочисленных делениях и умножениях.
P.S. Хотя, точность будет теряться при целочисленных делениях и умножениях.
Увы, тогда точность упадёт грохнется. Так как результат будет всегда равен целым секундам. А у меня они как раз скачут в районе секунды - поворот 660мс, прямой участок 531мм - 1474мс итп. И главное, нельзя получить результатом 0 - алгоритм может зациклиться. Собственно, я так на это переполнение набрёл - получил в результате переполнения при умножении отрицательное число (задрал один параметр до максимального значения), квадратный корень из него дал 0 и алгоритм зациклился.
Ещё можно на в целочисленных вычислениях на int64_t перейти. Это несильно замедлит вычисления (по сравнению с floag).
Ребята, приветствую, есть задача, которую я в принципе решил, но нужна консультация, может кто ее решил бы иначе или проще. Короче: имеем TM1628, задача - считать с него состояния кнопок в матрице с первой по двадцатую. Микросхема для этих целей имеет регистр размером в 5 байт, считывание производится последовательно. Все 5 байт мне не нужны, третий байт я не использую. Читаю с помощью команды shiftln, пишу в 4-хбайтную переменную.
Мой метод: переменной присваиваю значение 128, чтобы впоследствии иметь под рукой все 32 бита
Считываю в переменную первый байт (считываю по методу LSBFIRST, т. К в каждом регистре ТМ два последних бита всегда нулевые)
Сдвигаю биты в переменной на 8 бит влево
Читаю и записываю следующий бит тем же макаром.
Сдвигаю на 8
Третий (ненужный) бит просто читаю, никуда не записывая,
Четвертый читаю, пишу и сдвигаю, пятый просто читаю и пишу без сдвига.
В итоге имею набор из 32 бит с постоянным старшим в единице, который очень удобно разбирать при опросе кнопок, однако сама процедура считывания довольно громоздкая. Вопрос: можно ли упростить и оптимизировать? Код выложу позднее.
Добавлено after 26 minutes 16 seconds:
Вот код. Прошу сильно не пинать - пишу в среде ардуино, но не для ардуины, поэтому все же сюда настрочил - вроде как C, мать его.
Мой метод: переменной присваиваю значение 128, чтобы впоследствии иметь под рукой все 32 бита
Считываю в переменную первый байт (считываю по методу LSBFIRST, т. К в каждом регистре ТМ два последних бита всегда нулевые)
Сдвигаю биты в переменной на 8 бит влево
Читаю и записываю следующий бит тем же макаром.
Сдвигаю на 8
Третий (ненужный) бит просто читаю, никуда не записывая,
Четвертый читаю, пишу и сдвигаю, пятый просто читаю и пишу без сдвига.
В итоге имею набор из 32 бит с постоянным старшим в единице, который очень удобно разбирать при опросе кнопок, однако сама процедура считывания довольно громоздкая. Вопрос: можно ли упростить и оптимизировать? Код выложу позднее.
Добавлено after 26 minutes 16 seconds:
Вот код. Прошу сильно не пинать - пишу в среде ардуино, но не для ардуины, поэтому все же сюда настрочил - вроде как C, мать его.
Спойлер
КодКод: Выделить всё
void readTMData(unsigned long * data) {
digitalWrite(PIN_STB, LOW);
shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0x42); //Команда на чтение регистров с ТМ1628
pinMode(PIN_DIO, INPUT_PULLUP);
delayMicroseconds(1);
bitWrite(*data,7,1); // ставим 7-й бит в 1. После всех сдвигов он станет MSB. Маска ненажатых кнопок будет выглядеть как 10000000000000000000000000000000
* data =*data+ shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Считали и записали первый байт
* data= * data<<8; // Сдвинули
* data = *data+shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Считали и записали второй байт
* data= * data<<8; // Сдвинули
shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Вот тут просто считали, никуда не записывая, чтобы не рвать последовательность чтения
* data =*data+ shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Считали и записали четвертый байт
* data= * data<<8; // Сдвинули
* data = *data+shiftIn(PIN_DIO, PIN_CLK, LSBFIRST); // Считали и записали пятый байт
pinMode(PIN_DIO, OUTPUT);
digitalWrite(PIN_STB, HIGH);
}
Не важно чем все начнется. Важно чем кончится!
Идея:
В:
строка 25..38, посмотрите как написано shiftIn() для 8 бит. Напишите напр. локальную функцию (под другим именем) или просто перепишите логику для 4 * 8 бита (long) или больше (5 байт) (при этом, конечно, соблюдая разрядность новых типов данных - некоторые типы перейдут на uint64_t. А можете оптимизировать: до uint32_t, как написали напр. есть ненужный байт).
В:
Код: Выделить всё
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\wiring_shift.cКод: Выделить всё
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; ++i) {
digitalWrite(clockPin, HIGH);
if (bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);
digitalWrite(clockPin, LOW);
}
return value;
}
Последний раз редактировалось veso74 Вт авг 02, 2022 21:20:44, всего редактировалось 1 раз.


