Author: Dezhi Zhao
Date: 10:41:39 02/20/03
Go up one level in this thread
On February 20, 2003 at 12:49:39, Uri Blass wrote: >On February 20, 2003 at 12:19:22, Dezhi Zhao wrote: > >>On February 20, 2003 at 06:26:39, Uri Blass wrote: >> >>>On February 19, 2003 at 10:45:27, Dezhi Zhao wrote: >>> >>>>On February 19, 2003 at 09:57:13, Uri Blass wrote: >>>> >>>>>On February 19, 2003 at 09:41:35, Dezhi Zhao wrote: >>>>> >>>>>>On February 19, 2003 at 06:39:49, Uri Blass wrote: >>>>>> >>>>>>>I try to do movei faster and there are things that are supposed to do it >>>>>>>slightly faster but for some reasons do it slower so I deleted them(Maybe it is >>>>>>>better if I ignore it because it is a compiler optimization noise but I do not >>>>>>>like to see the program slower even if it is only 0.1% slower). >>>>>>> >>>>>>>Note that I do not use now compiler optimization except optimize for speed with >>>>>>>visual C++6. >>>>>>> >>>>>>> >>>>>>>Here is an example: >>>>>>>My function of adding pawn moves to the stack of moves get 2 numbers(from,to). >>>>>>> >>>>>>>I found that special functions to generate white moves one square forward,white >>>>>>>moves 2 pawns forward,black pawns one square forward,...helped me to do movei >>>>>>>faster. >>>>>>> >>>>>>>Common sense say that now I do not need 2 numbers in my functions because >>>>>>>I always have to=from-8 in >>>>>>> >>>>>>>Here is my function. >>>>>>>to is always from-8 and the question is if I can take advantage of that fact. >>>>>>> >>>>>>>static void gen_quietblackslowpawns(int from,int to) >>>>>>>{ >>>>>>> gen_t *g; >>>>>>> if (to<=7) >>>>>>> { >>>>>>> gen_promote(from,to); >>>>>>> return; >>>>>>> } >>>>>>> g=&gen_dat[first_move[ply+1]++]; >>>>>>> g->m.b.from=(char)from; >>>>>>> g->m.b.to=(char) to; >>>>>>> g->m.b.promote=0; >>>>>>> g->m.b.bits=16; >>>>>>> #if MODE!=MODE_PERFT >>>>>>> g->score = history[from][to]; >>>>>>> g->index=-10000; >>>>>>> #endif >>>>>>>} >>>>>> >>>>>>I think you can get a little from that fact. It will save a few push and pop >>>>>>operations. >>>>>> >>>>>>By the way, if you really want to optimize this function, you should consider >>>>>>re-designing the b structure so that the move can be saved in a single write >>>>>>operation, instead of 4. >>>>> >>>>>Thanks for the advise but how do I do it >>>>> >>>>>I have the same data structure as tscp here(Note that 90% of my code is >>>>>different than tscp but I copied part of it's data structures). >>>>> >>>>>Here is my b structure >>>>> >>>>>typedef struct >>>>>{ >>>>> char from; >>>>> char to; >>>>> char promote; >>>>> char bits; >>>>>} >>>>>move_bytes; >>>>> >>>>>typedef union >>>>>{ >>>>> move_bytes b; >>>>> int u; >>>>>} >>>>>move; >>>>> >>>>> >>>>>I can think about deleting the b and have something like >>>>>g->m.u=from+(to<<8)+(promote<<16)+bits<<24) but the question in that case is if >>>> >>>>yes. you can go this way. for this function, the last 2 items are simple >>>>constants anyways. >>>> >>>>>it is not going to do accesing the varaibles slower because there are places in >>>>>the code when I use bits and now I will need to use things like u>>24. >>>>> >>>>>I have no idea about the price of these things so I cannot evaluate speed here. >>>>> >>>>>Uri >>>> >>>>Not that complicated if you think it twice. I do know the semantics of bits >>>>thare. However I assume it is a flag. If it is the case, you do not need to do a >>>>shift to make it flat. Consider testing the other way without shift operations: >>>>u & (16 << 24) >>>>So you can avoid shift operations in many cases. So you still gain something >>>>here. >>>> >>>>dzhao >>> >>>I try it at this moment(I do not know if it is going to make the code faster so >>>I saved the previous code). >>> >>>The problem is how to make my code readable at the same time. >>> >>>I deleted the m.u and m.b.from,m.b,to,... >>>and have only m that is an integer. >>> >>>I try to use some defines >>> >>>#define mfrom (m&63) >>>#define mto ((m>>8)&63) >>>#define mpromote ((m>>16)&63) >>>#define mbits ((m>>24)&63) >>> >>>It was not enough so I added the following defines >>> >>>#define gen_dat_i_mfrom (gen_dat[i].m&63) >>>#define gen_dat_i_mto ((gen_dat[i].m>>8)&63) >>>#define gen_dat_i_mpromote ((gen_dat[i].m>>16)&63) >>>#define gen_dat_i_mbits ((gen_dat[i].m>>24)&63) >>> >>>I see that it is not enough and I need the same for other varaibles that are of >>>the same type. >>> >>>I do not like it so I went back to my previous code >>> >>>Thanks in advance for advices. >>> >>>Uri >> >>Here you may consider inline member functions, which give you the encapsulation >>and abstraction for free. The #define stuff is OK, but not as good. >> >>Such encapsulation and abstraction are valuable if you need to change such basic >>operations or data structure. Without them, you may face changing hundreds of >>scattered places, and if you miss a single one, you produce a bug. >> >>just a reminder: >>#define gen_dat_i_mpromote (gen_dat[i].m & (63 >> 16)) >>is better than: >>#define gen_dat_i_mpromote ((gen_dat[i].m>>16)&63) >> >>The same apply to other test operations. > >I guess that you mean >#define gen_dat_i_mpromote (gen_dat[i].m & (63 << 16)) > yes. >I guess that the laternative that I tried > >#define to(x) (((x)>>8)&255) was also bad >and better was >#define to(x) (((x)&255<<8) > >I guess that in that case I need to change some more code > >For example > >I have today some cases when I have >switch(m.bits) >case 1: >case 17: >... > >in that case I need to say case 1<<24 and in order not to have an ugly code >I need to have more constants for 2^24,2^24*17,... > >I can use >enum >{ > bits1=16777216 > bits17= >... >} > >Uri Rigth. You can name the constants by using either enum or #define. The same principle applies to the constants, not only for the cleaness but also for easy later modificafions.
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.