Как правильно следить за переполнением при арифметических операциях?

yulya

Программа должна быстро работать на процессоре без FPU. Профилировщик показывает, что большую часть времени занимают арифметические операции, в которых проводится проверка на переполнение примерно вот так:

Word32 L_var_out = L_var3 + mult;
if L_var3 ^ mult) & MIN_32) == 0L) && L_var_out ^ L_var3) & MIN_32 {
Overflow = 1;
return (L_var3 < 0L) ? MIN_32 : MAX_32;
}
else
return (L_var_out);

можно ли делать это более умно? к примеру, обращаться к процессору и спрашивать, не было ли переполнения?

Fmouse

целевых платформ несколько, раз пишете на C?

yulya

linux/gcc/arm

yulya

одна, то есть

Dasar

if L_var3 ^ mult) & MIN_32) == 0L) && L_var_out ^ L_var3) & MIN_32 {
как минимум стоит переставить условия

if L_var_out ^ L_var3) & MIN_32) && L_var3 ^ mult) & MIN_32) == 0L

vall

а там нет спецкоманд для сложения с насыщением?
такое часто необходимо при работе с изображениями.

yulya

мне уже подсказали — есть вот такое:
All other processor states are held in status registers. The current operating processor
status is in the Current Program Status Register (CPSR). The CPSR holds:
• four ALU flags (Negative, Zero, Carry, and Overflow
• two interrupt disable bits (one for each type of interrupt
• one bit to indicate ARM or Thumb execution
• five bits to encode the current processor mode
попробую этим воспользоваться. неясным остаётся только вопрос, как такая программа будет работать в многопоточной среде. ведь если между вычислениями и проверкой регистра вклинится что-то враждебное, будет ошибочка.

ppplva

Интересно, как условные переходы работают в многопоточной среде? :grin:

yulya

к чему ты это?

klyv

При переключении между нитями, сохраняются регистры. среди прочих - и регистр флагов.

yulya

не то чтобы я всё понял, но почему-то меня твои слова успокоили :)
не подскажешь, что небольшое можно прочитать, чтобы научиться работать с этим хозяйством? если с ассемблером незнаком

klyv

Нинай, нам это на лекциях на 2ом курсе рассказывали.

bleyman

Только учитывай, что overflow это вовсе не переполнение, а бит переноса из предстаршего разряда в старший =)
Для беззнаковых целых переполнение это carry, для знаковых - какая-то комбинация carry и overflow, точно не помню.

VitMix

Только учитывай, что overflow это вовсе не переполнение, а бит переноса из предстаршего разряда в старший =)
Вот тут: http://en.wikipedia.org/wiki/Overflow_flag написано, что "The overflow flag is usually computed as the xor of the carry into the sign bit and the carry out of the sign bit." и таким образом это как раз уже готовая к использованию комбинация carry и переноса из предстаршего в старший. Правда в этой статье всё на примере x86, и нигде не упоминается про Arm...

Fmouse

Раньше на ассемблере арма не писал. Вроде, такое должно проканать:
 
        MOV     R0, L_var3
MOV R1, mult
ADD R2, R1, R0
BCC no_overflow
OR R1, R0, &7FFFFFFF
ASR R2, R1, &01
.no_overflow ; Сейчас в R2 лежит результат
Оставить комментарий
Имя или ник:
Комментарий: