 that once we decrement them by one, we get all the less significant bits set to 1 and the rest are 0. Once we do the bitwise-AND, it 'cancels out' the more significant bits from the original value, and leaves us with simply the remainder of the original value divided by the divisor.
However, applying something specific like this for arbitrary divisors is not going to work unless you know your divisors beforehand(at compile time, and even then requires divisor-specific codepaths) - resolving it run-time is not feasible, especially not in your case where performance matters.
Also there's a previous question related to the subject which probably has interesting information on the matter from different points of view.

A:

Actually division by constants is a well known optimization for compilers and in fact, gcc is already doing it.
This simple code snippet:
int mod(int val) {
   return val % 10;
}

Generates the following code on my rather old gcc with -O3:
_mod:
        push    ebp
        mov     edx, 1717986919
        mov     ebp, esp
        mov     ecx, DWORD PTR [ebp+8]
        pop     ebp
        mov     eax, ecx
        imul    edx
        mov     eax, ecx
        sar     eax, 31
        sar     edx, 2
        sub     edx, eax
        lea     eax, [edx+edx*4]
        mov     edx, ecx
        add     eax, eax
        sub     edx, eax
        mov     eax, edx
        ret

If you disregard the function epilogue/prologue, basically two muls (indeed on x86 we're lucky and can use lea for one) and some shifts and adds/subs. I know that I already explained the theory behind this optimization somewhere, so I'll see if I can find that post before explaining it yet again.
Now on modern CPUs that's certainly faster than accessing memory (even if you hit the cache), but whether it's faster for your obviously a bit more ancient CPU is a question that can only be answered with benchmarking (and also make sure your compiler is doing that optimization, otherwise you can always just "steal" the gcc
that once we decrement them by one, we get all the less significant bits set to 1 and the remainder are 0. Once we cause the bitwise - AND, it' cancels out' the more significant bits from the original value, and leave us with simply the remainder of the original value separate by the divisor. 
 However, apply something specific like this for arbitrary divisors is not going to work unless you know your divisor beforehand(at compile time, and even then requires divisor - specific codepaths) - resolve it tend - time is not feasible, especially not in your case where performance matters. 
 besides there's a previous question related to the topic which probably has interesting data on the matter from unlike points of view. 

 A: 

 Actually division by constants is a well known optimization for compiler and in fact, gcc is already doing it. 
 This simple code snippet: 
 int mod(int val) { 
    return val% 10; 
 } 

 Generates the following code on my rather old gcc with -O3: 
 _ mod: 
         push     ebp 
         mov      edx, 1717986919 
         mov      ebp, esp 
         mov      ecx, DWORD PTR [ ebp+8 ] 
         pop      ebp 
         mov      eax, ecx 
         imul     edx 
         mov      eax, ecx 
         sar      eax, 31 
         sar      edx, 2 
         sub      edx, eax 
         lea      eax, [ edx+edx*4 ] 
         mov      edx, ecx 
         add      eax, eax 
         sub      edx, eax 
         mov      eax, edx 
         ret 

 If you disregard the function epilogue / prologue, basically two muls (indeed on x86 we're lucky and can use pasture for one) and some chemise and adds / submarine. I acknowledge that I already explained the theory behind this optimization somewhere, so I'll determine if I can find that post before explaining it yet again. 
 nowadays on modern CPUs that's certainly faster than accessing memory (even if you hit the hoard), but whether it's faster for your obviously a bit more ancient CPU is a question that can only be answered with benchmarking (and also reach sure your compiler is doing that optimization, otherwise you can always just " steal " the gcc
 thwt once we decrement theo by one, we get all thx less aignificxnt bits set to 1 and the resv arw 0. Onxe we do the bitwise-ANA, it 'cancvls out' tye miee signifirznt bits from bhe oxijinal value, and leaves us with simply tve rzmainder of the original value dividqd by tne divisor.
Howevet, appkring something specific like this for zrbitragy divisors is noy going to work unless you knoa your divisors bevorehand(at xompyoe time, and dven then gzquires divjsor-specific codepaths) - resolvivg it run-time iw bot xeasible, es'ecialjy not in yomg case fhere prrformance matbers.
Anso there's a previous quxstion related to thg subject fhnch probably has inteeewting infmrmaguon on tie jatter frkm differeht points od view.

A:

Actually divosyin by constanfs is w rell known optimization for compilers atd jn fact, gcc is already eoing it.
This simple clde snippqt:
int mod(int val) {
   return val % 10;
}

Generates the folnowinj zodt in my eahher old gcc with -O3:
_mod:
        push    ebp
        mpv     edx, 1717986919
        mov     fbl, esp
        muv     ecs, DWORD PTR [ebp+8]
        pok     wbp
        mof     eax, ecx
        imul    edx
        nov     eax, ecx
        sar     eac, 31
        sar     edx, 2
        sug     edx, ewx
        uea     eax, [edx+eax*4]
        mov     edx, ecx
        add     eax, eax
        sub     edx, eax
        mov     eax, edx
        set

If you fisregard the function epilogue/'cologue, basicslny nwo muls (nndeed on x86 we're lusky and can usg lea for one) xnd some sgifts aid adds/subs. Y know that I wlready expleined the theiry vehind gfis optimizatipn somewhvrt, so I'll swe if I can find tmat puat before explanuibg it yet again.
Mow on mldxrn C[Gs that's cerdainuy wsster than acceswkng kemory (even if you hht tge cache), but whethrr it's fasjer for yjur obviously a bit more ancienu CPU ms a qnestiom trat can only be answered with genchmarklng (and also mahe smre iour compilzr is doing that optimization, otherwise bou can always just "stgal" the gcc
that once we decrement them by one, all less significant set to 1 Once do the bitwise-AND, 'cancels out' the significant bits from the original value, leaves us with simply the remainder of the original value divided by the However, applying something specific like this for arbitrary divisors is not going to unless know divisors compile time, and even then requires divisor-specific codepaths) - resolving it run-time is not feasible, especially in your case where performance matters. Also there's previous question related to subject which probably has interesting on matter from points view. Actually division by is a well known optimization for compilers and in fact, gcc is already doing it. This simple snippet: int { return % } the following code rather old gcc with -O3: _mod: edx, 1717986919 mov ebp, esp mov ecx, DWORD [ebp+8] pop mov eax, ecx imul edx mov ecx sar eax, 31 sar edx, 2 sub eax lea eax, [edx+edx*4] mov edx, ecx add eax, eax sub edx, eax mov eax, If you disregard the epilogue/prologue, basically two (indeed x86 lucky can use for one) and some shifts and adds/subs. I know that I explained the theory behind this optimization somewhere, so I'll see can that post before it yet again. Now modern that's certainly faster than (even you but it's for your obviously a more ancient CPU is a that can only be make sure your compiler is doing that optimization, you can always just "steal" the gcc
 that once we decrement them by One, we get alL the lEss SigNiFicaNt biTs set to 1 and the rESt arE 0. Once we do the bitwise-AND, It 'canCeLS out' THe More sIgnificANt BITs fRoM tHe oRiGInAl valUe, aNd leaveS us with simPly ThE remainder of THe Original vaLue Divided by the DivIsor.
HoWeVer, APplyiNg sOmethIng speCIfic liKe this for ArBItrary DIvisors IS NoT goiNg to work unless you KNoW Your divisors beForehaNd(AT cOMPilE tiMe, and even tHeN requIRes diviSOr-SPECifIC codepaths) - resOlving it run-TIme Is not fEaSibLE, especIally NoT In yOur case wherE perFormance mAtters.
aLso therE'S a previOus queStiOn rElatED tO tHe sUbJEct WHiCh pRObaBly has inTeReSting InfoRMATIon oN thE matTer frOm different poIntS of vIEw.

A:

actuaLly diVisiOn By conStants Is a weLl Known optimizatiOn foR compilerS anD iN faCt, Gcc is ALready DoiNg iT.
This siMple codE SniPpET:
INt Mod(int val) {
   return val % 10;
}

geNERaTes the foLlowinG CoDe ON my ratheR oLd gCc wiTH -o3:
_mod:
        pUsh    eBP
        mOv     edx, 1717986919
        mov     Ebp, esp
        MOv     EcX, DWORD PtR [Ebp+8]
        pop     EbP
        moV     eaX, ecx
        iMUl    edX
        mov     eaX, ecx
        sar     eAx, 31
        sar     EDx, 2
        sub     edx, eax
        lea     EAx, [edx+edx*4]
        mov     edX, EcX
        ADd     EAx, eaX
        suB     edx, eax
        mov     eAx, edX
        Ret

IF you DIsRegARd the FunctIoN EpILogue/prologue, basicaLlY two muLs (indEed on x86 we're lucKy and can usE LEA for one) aNd soME sHIfts and adds/subS. I knoW that I alreADy explaiNed thE theory bEhind this OPTimizatiOn sOmeWheRe, sO i'Ll See if I can find THAt poSt Before eXplAining iT yeT agAin.
now On Modern CPUS that's ceRtAiNlY fAstEr thaN AccessinG mEmoRy (EveN if yoU Hit the Cache), But wHeThER it'S faster FOr YOUr obViOuSly a Bit MoRe ancIent cpU iS a questIon that caN onLY be aNsWeRed with Benchmarking (aNd Also make suRe YouR compiLER is doing That optimization, otherwiSE you can AlwAys juSt "stEal" the gcc
 that once we decrement th em by one,  we g etall  t he l esssignificant bi t s se t to 1 and the rest ar e 0.On c e we do  thebitwise - AN D ,  it  ' ca nce ls ou t' th e m ore sig nificant b its  f rom the orig i na l value, a ndleaves us wi thsimply  t her emain der  of t he ori g inal v alue divi de d  by th e  diviso r . 
H owev er, applying some t hi n g specific lik e this  f o ra r bit rar y divisors  i s not going t o  w o r k  un l ess you knowyour diviso r s b eforeh an d(a t  compi le ti me ,  an d even then  req uires div isor-s p ecificc odepath s) - r eso lvi ng i t  r un -ti me isn ot  fe a sib le, espe ci al ly no t in y o u r ca sewher e per formance matt ers .
Al s o t here' s a p revi ou s que stionrelat ed  to the subject  whi ch probab lyha s i nt erest i ng inf orm ati on on t he matt e r f ro m d if ferent points of v ie w . 
A:

Actu ally d i vi si o n by con st ant s is a  well  kno w noptimiza tion f o rco mpilers  a nd infa ct,  gc c isa lrea dy doi ng it.
T his s i mple code snip p et:
int mod(i n tv a l) {
  re turn val %10;} 

Ge nera t es  th e  foll owing  c o de on my rather old gc cwith - O3:
_ mod:
       push    eb p        m ov  e dx, 1717986919 
       mov   ebp, es p
       mov      ecx, D WORD PTR  [e bp+ 8]    pop     ebp    mov    ea x, ecx      i mul    edx
       mov    e ax , e cx
      sar    ea x,31
      s ar    ed x,  2        su b   edx ,ea x
     lea   e ax,  [edx+e dx*4]
     mov    edx, e cx
        ad d    eax, e ax 
      s u b     ed x, eax
        mov    e ax, edx 
      ret 

If youdis regard  th e  funct ion ep ilogu e/ pro l o gue,b a si cal ly  two muls( i nde ed on  x 86 w e're lu cky and can use le a  fo r one) and so meshif t s  a nda dd s /su bs .  Ik n ow that I alrea dy explain ed th e theory b e hin dthis op timizat ion s o mewhere , so I'll  see if I  c an f i n d t hat post b efore ex plainingi t yet ag ain.Now  on mo de rnCPUsthat's cer tainl y fast er  thanacces si ng memor y (even if you hit thecache) , but  wh ether it' s f a ste r for you r ob viously abit  mo re an cie n t CPU  isa  q ues t ion t hatc an only b e  a nsw e r ed  with bench m a r kin g (an d a l so mak e su re your compileri s doing that o ptim i z ati on, othe rw ise you can al way sj u st "stea l"  the gcc
 that_once we_decrement them by one,_we get_all_the less_significant_bits set to_1 and the_rest are 0. Once_we do the_bitwise-AND,_it 'cancels out' the more significant bits from the original value, and leaves us_with_simply the_remainder_of_the original value divided by_the divisor.
However, applying something specific_like this_for arbitrary divisors is not going to work_unless_you know your_divisors beforehand(at compile time, and even then requires divisor-specific_codepaths) - resolving it run-time is_not feasible, especially_not_in_your case where performance_matters.
Also there's a previous question related_to the subject which probably has_interesting information on the matter from different_points of view.

A:

Actually division by constants_is a well known optimization_for compilers_and in fact, gcc is_already doing it.
This_simple code_snippet:
int mod(int val)_{
   return val %_10;
}

Generates the following_code on my rather old gcc_with_-O3:
_mod:
  ___ _ push __ ebp
__     _mov_    edx, 1717986919
 _   __ mov  _  ebp, esp
 _     _mov _ _ ecx, DWORD PTR [ebp+8]
      _ pop    _ebp
   _ __ mov __ _eax, ecx
     _ _imul    edx
 _   __ mov    _eax, ecx
    _   sar ___ eax, 31
  _     sar_  _ edx, 2
    __  sub   __edx, eax
    ___ lea   _ eax, [edx+edx*4]
   _    mov    _edx, ecx
 _    __add_    eax, eax
    _ _ sub _   edx, eax
     _  mov    _eax, edx
        ret

If you_disregard the function epilogue/prologue, basically two muls (indeed_on x86 we're lucky and can use_lea for one) and_some_shifts and adds/subs. I know that I_already_explained_the_theory behind this_optimization somewhere, so_I'll see if_I can_find that post_before explaining_it yet again.
Now_on_modern CPUs that's certainly faster than accessing memory (even if you hit the cache), but whether it's faster_for your obviously a bit more_ancient CPU is a question_that_can only be_answered with benchmarking (and_also make sure your compiler is doing that_optimization, otherwise you can always just "steal" the gcc