2015-07-27 6 views
0

У меня есть две разные версии 64-битного дополнения в HLSL. Если я хочу, чтобы установить A + = B, где алы, ах, бл и ЧД является низким и высоким 32 битом A и B соответственно, то я либоВыполнение 64-битного добавления в HLSL, почему одна из моих реализаций дает неверные результаты?

(1):

#define pluseq64(al, ah, bl, bh) do {\ 
    uint tadd0 = al >> 1;\ 
    uint tadd1 = bl >> 1;\ 
    tadd0 += al & bl & 0x00000001;\ 
    tadd0 += tadd1;\ 
    tadd0 >>= 31;\ 
    al += bl;\ 
    ah += bh;\ 
    ah += tadd0; 

или (2):

#define pluseq64(al, ah, bl, bh) do {\ 
    uint t = al;\ 
    al += bl;\ 
    ah += bh;\ 
    if (al < t) { \ 
     ah += 1; \ 
    } } while(0) 

Теперь, что интересно, (1) всегда дает правильный выход, в то время как (2) не делает. Учитывая, что (1) является беспорядком операций (3 смены, 5 добавлений, чтобы сделать один 64 бит + =), я бы предпочел что-то по строкам (2) - (1), за исключением того, что (2) не работает должным образом.

В качестве альтернативы (2), я попытался:

#define pluseq64(al, ah, bl, bh) do {\ 
    uint t = al;\ 
    al += bl;\ 
    ah += bh;\ 
    ah += (al < t); } while(0) 

Что не совсем работает, либо (для вероятно по той же причине, что бы это ни причина есть, если у меня есть предположение).

Почему (2) не работают должным образом? Бонус: есть ли лучший способ сделать 64-битную добавку в HLSL?

Спасибо!

+0

Каков был вклад, в который он поступил неправильно? – harold

+0

Мне может потребоваться некоторое время, чтобы найти, где он отклоняется (нет возможности точки останова внутри GPU, бла). Интересно, что, когда я добавляю некоторые тестовые примеры, в которых будет присутствовать бит переноса, обе версии выдавали правильный результат ... но проблема остается в том, что совокупный вывод отличается от того, когда я использую версию 1 в отличие от версии 2. Это просто так странно. – MNagy

ответ

0

В моем тестировании три, кажется, производят эквивалентный вывод на C++, поэтому это довольно странно. Вы проводили тестирование процессора и работали ли вы там? Одна вещь, которую вы могли бы попробовать это пропустить макрос & сделать/в то время как вещи и посмотреть, если он работает с простой функцией HLSL:

void pluseq64(inout uint al, inout uint ah, in bl, in bh) 
{ 
    uint t = al; 
    al += bl; 
    ah += bh; 
    if (al < t) 
    { 
     ah += 1; 
    } 
    // or "ah += uint(al < t); 
} 

Функции встраиваются в HLSL в любом случае, так что я не думаю, что вы получите что-либо от использования препроцессора.