2013-03-12 3 views
0

Я хочу реализовать эффективную библиотеку для побитовых операций над большими целыми числами. Я написал следующую функцию, которая переопределяет BTEST:Лучший способ реализации побитовых операций для n-байтовых целых чисел

FUNCTION testb_i2b(n,i) 
    INTEGER(I8B), DIMENSION(0:), INTENT(IN) :: n 
    INTEGER(I2B), INTENT(IN) :: i 
    INTEGER(I2B) :: j 
    LOGICAL :: testb_i2b 
    j = ISHFT(i,-6) 
    IF (j .LE. UBOUND(n,1)) THEN 
    testb_i2b = BTEST(n(j),i-ISHFT(j,6)) 
    ELSE 
    testb_i2b = .FALSE. 
    END IF 
END FUNCTION testb_i2b 

Массив n содержит 64*(SIZE(n)-1) бит моего большого целого. Есть ли более эффективный способ получения одинаковой функциональности?

+0

Ваш BTEST слишком медленно? Является ли ваш aproach быстрее, по крайней мере, немного? Для какого компилятора? –

+0

Да, описанная выше реализация становится узким местом в моем коде. Я использую ifort. – delete000

ответ

3

Я не знаю, будет ли это быстрее, чем ваша версия. Я оставлю вас проверить это, но он включает в себя меньшее количество операций и не имеет явного выражения if. Он дает те же результаты, что и ваш код для нескольких тестов, которые я выполнил. Я проверил размер целых чисел в бигнаме на 64 бита, вы можете сделать этот параметр, если хотите.

LOGICAL FUNCTION btest_bignum(bn,ix) 
    IMPLICIT NONE 
    INTEGER(int64), DIMENSION(0:), INTENT(in) :: bn 
    INTEGER(int16), INTENT(in) :: ix 
    INTEGER :: array_ix 
    array_ix = ix/64 
    btest_bignum = BTEST(bn(array_ix), ix-(array_ix*64)) 
    END FUNCTION btest_bignum 

Обратите внимание, что я использовал теперь стандартный вид деклараций int64 и int16

+0

Главное отличие заключается в том, чтобы избежать IF (следовательно, проверка переполнения массива, которая будет быстрее). Умножение и разделение будут скомпилированы для переключения инструкций в любом случае. – 2013-03-12 19:36:48

+0

большое спасибо, мой код работает на 10% быстрее. – delete000

Смежные вопросы