- posted
20 years ago
char[] & MSP430
- Vote on answer
- posted
20 years ago
- Vote on answer
- posted
20 years ago
- Vote on answer
- posted
20 years ago
- Vote on answer
- posted
20 years ago
- Vote on answer
- posted
20 years ago
AM>> if(putptr == input_buffer + sizeof(input_buffer)) AM>> putptr = input_buffer;
DT> А про операцию взятия модуля не слышал? :) Я примерно это делал примерно DT> так; стиль, естественно, паскалевский. ;)
DT> #define QBUF_SIZE 16 DT> #define QBUF_SIZE_IS_POWER_OF_TWO 1 //set to 0 if QBUF_SIZE ISN'T a
Чтобы не полагаться на чтение комментариев - вместо второй строки
#if (QBUF_SIZE) & (QBUF_SIZE-1) #define QBUF_SIZE_IS_POWER_OF_TWO 0 #else #define QBUF_SIZE_IS_POWER_OF_TWO 1 #endif
DT> { DT> #if QBUF_SIZE_IS_POWER_OF_TWO DT> return (x+1) & (QBUF_SIZE-1); Это нормально.
DT> #else DT> return (x+1) % QBUF_SIZE; Это очень долго на всех, пожалуй, 8-битках и на очень многих 16-битках. На которых не очень долго - почти наверняка просто долго.
Ну и индексы вместо указателей хоть и могут сэкономить ОЗУ (если они 8-битные а указатели уже нужны 16-битные), но код и время выполнения увеличат.
wbr,
- Vote on answer
- posted
20 years ago
- Vote on answer
- posted
20 years ago
- Vote on answer
- posted
20 years ago
DT>>> return (x+1) % QBUF_SIZE; OR>> Это очень долго на всех, пожалуй, 8-битках и на очень многих 16-битках.
DT> Если деления нет... Ну вот я и очертил -- где его нет или оно очень медленное по сравнению с остальными действиями.
OR>> Hу и индексы вместо указателей хоть и могут сэкономить ОЗУ OR>> (если они 8-битные а указатели уже нужны 16-битные), но код и время OR>> выполнения увеличат.
DT> Для меня важнее надёжность, безопасность и читаемость (которая тоже DT> обычно DT> надёжности прибавляет). Согласись, что индексирование массива - более DT> "прозрачная" операция. После паскаля. А после ассемблера - ещё вопрос. В стандарте С специально гарантируется, что указатель сразу за концом массива - валиден для операций сравнения и адресной арифметики (но не для обращения). Чтобы можно было делать out = *outptr++; if ( outptr >= buffer+BUFSIZE ) outptr = buffer; а не out = *outptr; if ( outptr == buffer+BUFSIZE-1) outptr = buffer; else ++outptr;
Там, правда, возникает один философский вопрос, но в реальных системах он как-то решается
DT> Да и проверка на переполнение с указателями получается некрасивой. Чем же?
wbr,
- Vote on answer
- posted
20 years ago
- Vote on answer
- posted
20 years ago
DO>> можно кстати не заморачиваться условной компиляцией. ИАР 2.28 нормально DO>> тутсоображает. вот код во что у меня собирается:
DO>> if(((U8)(uart_sq.tail + 1) % UART_Q_SIZE) == uart_sq.head) return -1;
DT> А! Hу так это же надо было сообразить, что результат сложения байта с DT> константой будет типа int. ;) Ничего соображать не надо. Integer promotion rules - прочесть один раз и запомнить.
Некоторые эхотажные компиляторы достаточно хорошо оптимизируют, чтобы соптимизировать эти правила, некотоыре имеют ключик для их отключения. У некоторых остаются недооптимизированные хвосты.
В данном случае компилятор самовольничать не имел права, так как по этим правилам при .tail = 255 результат выражения
uart_sq.tail + 1
будет равен 256, а
256 % UART_Q_SIZEотнюдь не обязано быть равно
0 % UART_Q_SIZEПоскольку он ничего не знает о том, в каких пределах реально меняется .tail -- он не мог знать, что .tail + 1 всегда меньше 256 и можно уоптимизировать до работы с U8.
wbr,
- Vote on answer
- posted
20 years ago