View conditional IF code to save processor cycles

I am considering using the if condition in my program, there are lines like the following:

if(count > 4) count = 4;

Would it be nice to write the conditional expression condition above as the next unramified?

count = 4*(count> 4) + count*(count<= 4);

I also have the following snippet:

for (j=0, i=0; j<NCARD_PER_SUIT && i<CARDS_PER_PLAYER+CARDS_ON_BOARD; ++j) {
    if (card_cfg.hearts & cfg_mask[j]) {
        player_hand[i].card.face = j;
        player_hand[i++].card.suit = HEART;
    }
    if (card_cfg.spades & cfg_mask[j]) {
        player_hand[i].card.face = j;
        player_hand[i++].card.suit = SPADE;
    }
    if (card_cfg.clubs & cfg_mask[j]) {
        player_hand[i].card.face = j;
        player_hand[i++].card.suit = CLUB;
    }
    if (card_cfg.diamonds & cfg_mask[j]) {
        player_hand[i].card.face = j;
        player_hand[i++].card.suit = DIAMOND;
    }
}

and I wonder if there is a good (unbranched) way to write above, any suggestions?

EDIT: based on some feedback, I compared the assembly instructions (using MSVS2015 for Windows 10) and got the following:

; 718  :     count = 4*(count> 4) + count*(count<= 4);

xor ebx, ebx
cmp edx, 4
setle   bl
xor ecx, ecx
imul    ebx, edx
cmp edx, 4
mov edx, 4
cmovg   ecx, edx
add ebx, ecx

And if you go back to the if statement, I get the following if the jump instruction and the total number of 2/3 commands are not comparable with the above:

; 718  :     if( count >4) count = 4;

mov eax, DWORD PTR _i$6$[ebp]
cmp edx, edi
mov ebx, DWORD PTR _player$GSCopy$1$[ebp]
cmovg   edx, edi
mov edi, DWORD PTR _count$1$[ebp]
mov DWORD PTR _count$4$[ebp], edx

EDIT # 2: based on the hint from the comments below, I went ahead and created

union 
typedef union {
    struct cfg {
        unsigned short hearts;  
        unsigned short spades;
        unsigned short clubs;
        unsigned short diamonds;
    } suit;
    unsigned long long allsuits;
} card_cfg_t;

OP : , sot (20% ), 64- ( 40%), 32- :

for (j=0, i=0; j<NCARD_PER_SUIT && i<CARDS_PER_PLAYER+CARDS_ON_BOARD; ++j) {
    for (int k=0; k<4; ++k) {
        present = (int)((card_cfg.allsuits & (cfg_mask[j] << 16*k)) != 0);
        player_hand[i].card.face = j*present;
        player_hand[i].card.suit = k;
        i = i + present;
    }
}
+4
2

, ( - - ):

int count;

 void foo()
 {
       count = 4*(count> 4) + count*(count <= 4);
 }

 void foo1()
 {
       count = count > 4 ? 4 : count;
 }

  void foo4()
 {
       if(count> 4) count = 4;
 }

foo:
  mov edx, DWORD PTR count[rip]
  xor ecx, ecx
  cmp edx, 4
  setle al
  setg cl
  movzx eax, al
  imul eax, edx
  lea eax, [rax+rcx*4]
  mov DWORD PTR count[rip], eax
  ret
foo1:
  cmp DWORD PTR count[rip], 4
  mov eax, 4
  cmovle eax, DWORD PTR count[rip]
  mov DWORD PTR count[rip], eax
  ret
foo4:
  cmp DWORD PTR count[rip], 4
  jle .L6
  mov DWORD PTR count[rip], 4
.L6:
  rep ret
+1

:

     pushcards(player, popcards(dealer));
+1

Source: https://habr.com/ru/post/1684677/


All Articles