Вы можете профилировать этот вариант (без ветвления) и опубликовать результат? Мне любопытно ... (может быть, медленнее, если вы пишете те 255 в pTex редко, так как этот код будет касаться каждого байта pTex or
).
#include <string>
#define IJ_REF(_i, _j) ((_j)*nx_+(_i))
#define HAS_BIT(_v, _bit) (((_v) & (_bit)) == (_bit))
int main()
{
constexpr uint32_t ny_ = 350, nx_ = 350;
constexpr uint8_t FLAG = 2;
uint8_t image_[ny_*nx_];
uint8_t pTex[ny_*nx_*4];
// let access pTex by uint32_t directly
uint32_t *pTex32bPtr = reinterpret_cast<uint32_t *>(pTex);
// debug input
image_[IJ_REF(nx_-2, ny_-1)] = FLAG;
image_[IJ_REF(nx_-1, ny_-1)] = ~FLAG;
pTex32bPtr[IJ_REF(nx_-2, ny_-1)] = 0x12345678;
pTex32bPtr[IJ_REF(nx_-1, ny_-1)] = 0x12345678;
// prepare for loop
const uint32_t endOfs = ny_*nx_;
constexpr uint32_t pTexORValue[2] = {0, 0xFFFFFFFF};
// loop trough all [x,y] values
for (uint32_t srcOfs = 0; srcOfs < endOfs; ++srcOfs) {
unsigned ORindex = !HAS_BIT(image_[srcOfs], FLAG);
// if you know FLAG is always 2, it can be:
// ORindex = image_[srcOfs]&2; with pTexORValue array:
// [3] = {0xFFFFFFFF, 0, 0};
pTex32bPtr[srcOfs] |= pTexORValue[ORindex];
}
// debug output
for (size_t i = IJ_REF(nx_-2, ny_-1) * 4; i < IJ_REF(nx_, ny_-1)*4; ++i) {
printf(" %02x", pTex[i]);
}
}
Также я вроде удивления, почему компилятор делает movzx edx
+ and edx
, в то время как он мог бы сделать test byte ptr [eax+ecx],2
вместо этого. Что такое тип FLAG
? О, теперь я вижу, это из-за вашего HAS_BIT
макроса. Это тест «has_all_bits».
Если вы планируете тестировать только один бит, или любой-в-бит хорошо, вы должны попробовать (это должно позволить test
использования):
#define HAS_SOME_BIT(_v, _bits) (((_v) & (_bits)) != 0)
Это может помочь даже тот код, который я выше лучше оптимизироваться.
И в сборе с FLAG фиксированной как 2 было бы даже можно вычислить значение ИЛИ как:
mov ebx,image_offset
loop:
movzx eax,Image_[ebx]
; copy bit 0x02 to all 32 bits
shl eax,30
sar eax,31
not eax ; flip it to "not HAS_BIT"
or pTex[ebx*4],eax
...
Вы не должны начать свои идентификаторы с подчеркиванием. Эти идентификаторы зарезервированы для реализации вашего компилятора. – PaulMcKenzie
@PaulMcKenzie это макроопределения, которые будут заменены до компиляции, но вы правы, я не должен. – zoujyjs
И само по себе не должно быть дорогостоящим, но, возможно, вы путаете дерьмо из предсказателя ветви, особенно если нет реальной картины того, действительно ли это условие. Затем вы проводите много времени, ожидая, когда трубопровод будет промывать. –