Поскольку я - зануда,
Как записать код лаконичнее
Re: Как записать код лаконичнее
[uquote="MLX90640",url="/forum/viewtopic.php?p=4312142#p4312142"]Да нет, просто использует более выгодный по скорости порядок и состав инструкций.[/uquote]
Поскольку я - зануда,
то как вцеплюсь - не отстаю. А кто мне мешает этот же "более выгодный по скорости порядок и состав инструкций" расписать на асме во вставке? Я вот голословно
утверждаю, что умный компилятор может разработать код, который по быстродействию не хуже сделанного на асме (умным программистом), но чтобы лучше - для этого нет никаких предпосылок.
Поскольку я - зануда,
- Реклама
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Как записать код лаконичнее
[uquote="Jack_A",url="/forum/viewtopic.php?p=4312145#p4312145"]А кто мне мешает этот же "более выгодный по скорости порядок и состав инструкций" расписать на асме во вставке?[/uquote]Никто не мешает, но в данном случае вы этого не сделали. Результат компилятора с -O3 быстрее оказался.
В данном случае компилятор применил разворачивание цикла. Команд больше, а выполняются быстрее. Есть и другие методы оптимизации. А главное, достаточно поменять ключ оптимизации и не надо переписывать вставку.
В данном случае компилятор применил разворачивание цикла. Команд больше, а выполняются быстрее. Есть и другие методы оптимизации. А главное, достаточно поменять ключ оптимизации и не надо переписывать вставку.
Re: Как записать код лаконичнее
Я бы сделал, но это не особо занимало. Ничего бы разворачивать не стал, разместил бы один, по крайней мере, массив на грани 256-байтного сегмента (ведь сказано было - это возможно), и парметром цикла был бы ZL, не проверяя ZН и не используя отдельный счётчик. Было бы, как минимум, не медленнее. Но мне лень что-то доказывать, в чём я сам уверен.
Но самый быстрый способ, конечно, это был бы (как это сделал один в этом топике
) - сорок сравнений в ряд, без всяких циклов. Ну что ж, как говорил мой дядюшка - "в ^^^^^^^^^^м доме и не такое делают" 
Код: Выделить всё
LDI ZL,low(Array1)
LDI ZH,highArray1)
LDI YL,low(Array2)
LDI YH,high(Array2)
lab: ld R16,z+
ld R1,y+
sub R16.R1
brne out_cycle
cpi ZL,low(Array1+40)
brlo lab
out_cycle: tst R16 ; вот сюда мы придём с 0 в R16 , если массивы совпали :))- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Как записать код лаконичнее
[uquote="Jack_A",url="/forum/viewtopic.php?p=4312156#p4312156"]Но самый быстрый способ, конечно, это был бы (как это сделал один в этом топике
)[/uquote]Дошло?
Лаконичный код ТС быстрее вашей вставки и выполняется за 6 тактов на один элемент массива! 
Продолжаем ржать над ТС?
Продолжаем ржать над ТС?
Re: Как записать код лаконичнее
Зачем? Ему виднее - скорость или компактность нужна. Но никак не вяжется с заглавием темы:


Может, под этим словом он подразумевает "быстрее" ? Мой телепатор перегрелся, пойду кваску хлебну.Как записать код лаконичнее
Спойлер
В разделе юмора "Литературки" когда-то ( в прошлом веке ) было: "Выразитесь несколько раз лаконически (без ущерба для себя) "- Реклама
Re: Как записать код лаконичнее
А asm его ни кто не глянул?MLX90640 писал(а):Ну а топикстартер конечно же всех просто уделал, применив свой, наиболее "лаконичный" способВот, "учитесь"!
Его asm с оптимизацией -Os соответствует asm VladislavS с -O3, один в один, и по быстродействию выходит так же 51мкс. Другая проблема - полученный в результате размер кода.
Re: Как записать код лаконичнее
Беда в том, что если ТС не знает как использовать цикл, то вызвать функцию с аргументами и подавно.(
Re: Как записать код лаконичнее
ТС использует то, что ему понятно, а не то, что вы тут ему нахимичили.
Кстати код VladislavS можно и под -Os собрать
Кстати код VladislavS можно и под -Os собрать
Спойлер
Код: Выделить всё
uint8_t arr1[8] = {1,2,3,4,5,6,7,8};
uint8_t arr2[8] = {1,2,3,4,5,6,7,9};
uint8_t result=0;
inline uint8_t my_memcmp(uint8_t* buf1, uint8_t* buf2, uint8_t count) __attribute__((always_inline));
#pragma GCC push_options
#pragma GCC optimize ("O3")
inline uint8_t my_memcmp(uint8_t* buf1, uint8_t* buf2, uint8_t count)
{
while(count--)
{
if(*buf1++ != *buf2++) return 1;
}
return 0;
}
#pragma GCC push_options
int main()
{
result = my_memcmp(arr1,arr2,8);
for (;;);
}- KorbenDallas
- Встал на лапы
- Сообщения: 93
- Зарегистрирован: Пн окт 31, 2016 06:23:19
Re: Как записать код лаконичнее
Код: Выделить всё
uint8_t arr1[8] = {1,2,3,4,5,6,7,8};
uint8_t arr2[8] = {1,2,3,4,5,6,7,9};
uint8_t result=0;Добавляем `static` и
Код: Выделить всё
main:
.L2:
rjmp .L2А если серьезно, то кто знает какие еще оптимизации были подавлены вашим использованием переменных с external linkage? Хотите тестировать оптимизационные возможности компилятора - не давайте ему полностью выкинуть всю функциональность (напр. `static volatile uint8_t result=0;`), но ни о каких переменных с external linkage речь быть не может. Как не может идти речи ни о каком программирования на С без массивного использования `const` и `restrict`.
Кстати, несмотря на то, что GCC - самый слабый компилятор из "большой тройки", меня сильно удивило то, что он в таком случае не не догадывается выполнить сравнение на стадии компиляции. Clang догадался.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Как записать код лаконичнее
Во-первых, тема отнюдь не про "оптимизацию производительности", вы невнимательно её читали.
Во-вторых, вы правда считаете, что все вокруг идиоты и не знают про возможности компилятора просчитать результат на этапе компиляции? Собственно, результат очевиден даже без компиляции "на глаз". А речь идёт именно о сравнении массивов в рантайме.
В-третьих, применительно к AVR gcc уж точно не самый слабый. Да и "большой тройки" как таковой для AVR не существует. IAR на этой задаче, кстати, слил по полной. Результат даже приводить не буду.
Во-вторых, вы правда считаете, что все вокруг идиоты и не знают про возможности компилятора просчитать результат на этапе компиляции? Собственно, результат очевиден даже без компиляции "на глаз". А речь идёт именно о сравнении массивов в рантайме.
В-третьих, применительно к AVR gcc уж точно не самый слабый. Да и "большой тройки" как таковой для AVR не существует. IAR на этой задаче, кстати, слил по полной. Результат даже приводить не буду.
Re: Как записать код лаконичнее
KorbenDallas, хорошо, давайте массивы заставим поработать
1 кодТак сойдет?
На -Os 141мкс 320байт
на -O3 55мкс 388байт2 кодНа -Os и -O3 asm-код одинаковый, 53мкс 384байт 
1 код
Спойлер
Код: Выделить всё
volatile uint8_t arr1[8] = {1,2,3,4,5,6,7,8};
volatile uint8_t arr2[8] = {1,2,3,4,5,6,7,9};
volatile uint8_t result=0;
inline uint8_t my_memcmp(volatile uint8_t* buf1, volatile uint8_t* buf2, uint8_t count) __attribute__((always_inline));
inline uint8_t my_memcmp(volatile uint8_t* buf1, volatile uint8_t* buf2, uint8_t count)
{
while(count--)
{
if(*buf1++ != *buf2++) return 1;
}
return 0;
}
int main()
{
while (1)
{
result = my_memcmp(arr1,arr2,8);
arr1[0]++; arr1[1]++; arr1[2]++; arr1[3]++; arr1[4]++; arr1[5]++; arr1[6]++; arr1[7]++;
arr2[0]++; arr2[1]++; arr2[2]++; arr2[3]++; arr2[4]++; arr2[5]++; arr2[6]++; arr2[7]++;
}
}На -Os 141мкс 320байт
на -O3 55мкс 388байт
Спойлер
Код: Выделить всё
volatile char x1[8] = {1, 2, 3, 4, 5, 6, 7, 8};
volatile char x2[8] = {1, 2, 3, 4, 5, 6, 7, 9};
volatile uint8_t result=0;
int main(){
while (1)
{
if((x1[0] == x2[0])
&&(x1[1] == x2[1])
&&(x1[2] == x2[2])
&&(x1[3] == x2[3])
&&(x1[4] == x2[4])
&&(x1[5] == x2[5])
&&(x1[6] == x2[6])
&&(x1[7] == x2[7])
) result=0;
else result=1;
x1[0]++; x1[1]++; x1[2]++; x1[3]++; x1[4]++; x1[5]++; x1[6]++; x1[7]++;
x2[0]++; x2[1]++; x2[2]++; x2[3]++; x2[4]++; x2[5]++; x2[6]++; x2[7]++;
}
}


