你可以分析這個變體(無分支)和後的結果?我很好奇......(可能會比較慢,如果您很少將這些255寫入pTex,由於此代碼將觸碰每個含有or
的pTex字節)。
#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
和本身不應該是昂貴的,但也許你會混淆分支預測器的垃圾,特別是如果沒有真正的模式來判斷這種情況是否屬實。然後你花了很多時間等待管道沖洗。 –