LMR revisited.

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: LMR revisited.

Post by bob »

Kempelen wrote:Another stupid idea came to me mind: what about to reduce moves does goes backward? i.e, for white side those with goes from file>4 to a file<=2 . Even maybe with a few more conditions to recognize a useless moves
Already tried. :)

For the last three points discussed so far...

reducing passed pawn pushes (default does not). -2 Elo.

reducing captures (default does not). -2 Elo

Not reducing pawn pushes (default does). -10 Elo

Note that the error bar is +/-4, so the above (except for the last) is a "stretch".

Here's results, each test run 3 times. R01 reduces passed pawn pushes, R02 reduces captures, R03 does not reduce any pawn push. each was run 3 times.

Code: Select all

Rank Name               Elo    +    - games score oppo. draws
   1 Glaurung 2.2       2667    3    3 93384   59%  2602   22% 
   2 Toga2              2658    3    2 93384   58%  2602   22% 
   3 Crafty-23.0-3      2608    4    4 31128   52%  2595   22% 
   4 Crafty-23.0-2      2606    4    4 31128   52%  2595   22% 
   5 Crafty-23.0-1      2606    4    4 31128   51%  2595   22% 
   6 Crafty-23.1R01-3   2604    4    4 31128   51%  2595   22% 
   7 Crafty-23.1R01-2   2603    5    5 31128   51%  2595   22% 
   8 Crafty-23.1R01-1   2603    5    5 31128   51%  2595   22% 
   9 Crafty-23.1R02-2   2603    5    5 31128   51%  2595   22% 
  10 Crafty-23.1R02-1   2602    4    4 31128   51%  2595   22% 
  11 Crafty-23.1R02-3   2602    4    4 31128   51%  2595   23% 
  12 Crafty-23.1R03-1   2595    4    4 31128   50%  2595   22% 
  13 Crafty-23.1R03-3   2594    5    5 31128   50%  2595   22% 
  14 Crafty-23.1R03-2   2594    5    5 31128   50%  2595   21% 
  15 Fruit 2.1          2558    3    3 93384   44%  2602   24% 
  16 Glaurung 1.1 SMP   2496    4    4 93384   36%  2602   20% 
User avatar
Kempelen
Posts: 620
Joined: Fri Feb 08, 2008 10:44 am
Location: Madrid - Spain

Re: LMR revisited.

Post by Kempelen »

Again I have another idea about not only reductions, but extensions at the rood node.

In iteration N, if a move that in N-2 iteration had a x% of the tree size, and in N-1 had 30% more than x, it would be good to extend, as it promises.

In the other side, if a move than in N-2 iteration had y% of the tree size, and in N-1 had 30% less than y, it would be safe to reduce, as it appear to be bad.

(in this examples, 30% is only an example. you could play with that margin)

It comes to my mind this evening, but as you have tested nearly all it is probably a bad idea.

Regards,
FS
Fermin Serrano
Author of 'Rodin' engine
http://sites.google.com/site/clonfsp/
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: LMR revisited.

Post by bob »

Kempelen wrote:Again I have another idea about not only reductions, but extensions at the rood node.

In iteration N, if a move that in N-2 iteration had a x% of the tree size, and in N-1 had 30% more than x, it would be good to extend, as it promises.

In the other side, if a move than in N-2 iteration had y% of the tree size, and in N-1 had 30% less than y, it would be safe to reduce, as it appear to be bad.

(in this examples, 30% is only an example. you could play with that margin)

It comes to my mind this evening, but as you have tested nearly all it is probably a bad idea.

Regards,
FS
I am already doing this, except I don't extend. However, I look at the size of each root sub-tree and those that are larger than the rest by some significant margin are flagged to be searched one at a time, all processors searching a single move, before I start the normal split-at-the-root after the first move is searched. In my case it is split-at-the-root after the first N moves are searched, where N is based on the sub-tree size. I also tried using this flag to not reduce the moves that appear promising, but it was slightly worse. Almost everything seems to be slightly worse, except for those things that are "no change". :)
CThinker
Posts: 388
Joined: Wed Mar 08, 2006 10:08 pm

Re: LMR revisited.

Post by CThinker »

bob wrote:I have been experimenting with LMR and various ways one might do it more intelligently. And after about 4 weeks of solid testing, I have produced exactly -nothing- that helps. I have tried things from using a complex ordering early in the tree, and then using either one or two "late" counters, one for PV nodes, one for non-PV nodes (ala glaurung). Doesn't help one bit. Just doing the counters without the ordering. nada. I've tried (again) fruit-like history counters. Either no better or much worse depending on the threshold set. I've tried a more localized history counter, like failhi[ply][from-to] and faillo[ply][from-to] so that the values don't get completely scrambled. Again, either no better or worse depending on how those values are used.

I'm still testing, but so far, looking at several programs that do LMR, absolutely none of the ideas I have seen make any difference at all in testing, unless they make the program weaker. I have tested with very fast games, 1+1 games, 5+5 games, and even a few 60+60 tests (those turn into 3 hours + per game, which means I can play about 256 games every 3 hours, which is really too slow to be usable. But I wanted to make sure that the things I was trying were not just tested on very fast games where they might not matter.

I've tested everything in Glaurung 2, fruit 2, toga 2, and a lot of other ideas as well (some given above, not all). This appears to be an idea that either works, or it doesn't. Tuning seems to either hurt or have no impact.

If anyone has any suggestions while I am testing this stuff, feel free to make suggestions. I'd suspect I have tried at least 75% of what will be suggested, but any new ideas are welcome. I've been convinced for a couple of years now that the history-counter approach is simply no good, and I've not been using that for at least that long now. Some of the other ideas I tried I thought would help, but they didn't.

This is a peculiar algorithm, to say the least, since most things can be tuned somewhat. But this is resisting every effort I throw at it...
From my experience, there are two things that affect the effectiveness of LMR:

1. The type of evaluation function.

Thinker has 3 types of eval functions, and I noticed that the more material-oriented eval benefits little from LMR. My guess is that this is because the chances of improving the score with non-captures is smaller.

2. Move ordering of non-captures.

I noticed that if there is no move ordering of non-captures, some good moves can get reduced, or bad moves get searched in full depth. This is no different from doing no LMR at all. You are just at the mercy of the move generator.

In my experience, the non-captures should be sorted in some way, and then LMR would make sense.

Now, because every engine is unique (except for the clones/derivatives/replicates), these findings may not apply to other engines.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: LMR revisited.

Post by bob »

CThinker wrote:
bob wrote:I have been experimenting with LMR and various ways one might do it more intelligently. And after about 4 weeks of solid testing, I have produced exactly -nothing- that helps. I have tried things from using a complex ordering early in the tree, and then using either one or two "late" counters, one for PV nodes, one for non-PV nodes (ala glaurung). Doesn't help one bit. Just doing the counters without the ordering. nada. I've tried (again) fruit-like history counters. Either no better or much worse depending on the threshold set. I've tried a more localized history counter, like failhi[ply][from-to] and faillo[ply][from-to] so that the values don't get completely scrambled. Again, either no better or worse depending on how those values are used.

I'm still testing, but so far, looking at several programs that do LMR, absolutely none of the ideas I have seen make any difference at all in testing, unless they make the program weaker. I have tested with very fast games, 1+1 games, 5+5 games, and even a few 60+60 tests (those turn into 3 hours + per game, which means I can play about 256 games every 3 hours, which is really too slow to be usable. But I wanted to make sure that the things I was trying were not just tested on very fast games where they might not matter.

I've tested everything in Glaurung 2, fruit 2, toga 2, and a lot of other ideas as well (some given above, not all). This appears to be an idea that either works, or it doesn't. Tuning seems to either hurt or have no impact.

If anyone has any suggestions while I am testing this stuff, feel free to make suggestions. I'd suspect I have tried at least 75% of what will be suggested, but any new ideas are welcome. I've been convinced for a couple of years now that the history-counter approach is simply no good, and I've not been using that for at least that long now. Some of the other ideas I tried I thought would help, but they didn't.

This is a peculiar algorithm, to say the least, since most things can be tuned somewhat. But this is resisting every effort I throw at it...
From my experience, there are two things that affect the effectiveness of LMR:

1. The type of evaluation function.

Thinker has 3 types of eval functions, and I noticed that the more material-oriented eval benefits little from LMR. My guess is that this is because the chances of improving the score with non-captures is smaller.

2. Move ordering of non-captures.

I noticed that if there is no move ordering of non-captures, some good moves can get reduced, or bad moves get searched in full depth. This is no different from doing no LMR at all. You are just at the mercy of the move generator.

In my experience, the non-captures should be sorted in some way, and then LMR would make sense.

Now, because every engine is unique (except for the clones/derivatives/replicates), these findings may not apply to other engines.
The problem is, this is not borne out by testing. I have tried ordering non-captures with a complete static eval, a complete static eval + SEE() of the move being ordered, etc. And I get absolutely no benefit of any kind either in short or long games. I tried both of the above in conjunction with looking at a variable number of early-sorted moves before starting to reduce. In every last case this reduced Elo as the number was increased (which means doing fewer reductions). I even tried the oft-mentioned idea of treating PV vs non-PV nodes differently. Hurt in every case any time I reduce less... The only exceptions I have found is that reducing captures hurts a little, reducing passed pawn pushes hurts almost nothing. Reducing checks is a 15 Elo drop or so (these results are elsewhere in this thread in fact.)
Edsel Apostol
Posts: 803
Joined: Mon Jul 17, 2006 5:53 am
Full name: Edsel Apostol

Re: LMR revisited.

Post by Edsel Apostol »

bob wrote:
CThinker wrote:
bob wrote:I have been experimenting with LMR and various ways one might do it more intelligently. And after about 4 weeks of solid testing, I have produced exactly -nothing- that helps. I have tried things from using a complex ordering early in the tree, and then using either one or two "late" counters, one for PV nodes, one for non-PV nodes (ala glaurung). Doesn't help one bit. Just doing the counters without the ordering. nada. I've tried (again) fruit-like history counters. Either no better or much worse depending on the threshold set. I've tried a more localized history counter, like failhi[ply][from-to] and faillo[ply][from-to] so that the values don't get completely scrambled. Again, either no better or worse depending on how those values are used.

I'm still testing, but so far, looking at several programs that do LMR, absolutely none of the ideas I have seen make any difference at all in testing, unless they make the program weaker. I have tested with very fast games, 1+1 games, 5+5 games, and even a few 60+60 tests (those turn into 3 hours + per game, which means I can play about 256 games every 3 hours, which is really too slow to be usable. But I wanted to make sure that the things I was trying were not just tested on very fast games where they might not matter.

I've tested everything in Glaurung 2, fruit 2, toga 2, and a lot of other ideas as well (some given above, not all). This appears to be an idea that either works, or it doesn't. Tuning seems to either hurt or have no impact.

If anyone has any suggestions while I am testing this stuff, feel free to make suggestions. I'd suspect I have tried at least 75% of what will be suggested, but any new ideas are welcome. I've been convinced for a couple of years now that the history-counter approach is simply no good, and I've not been using that for at least that long now. Some of the other ideas I tried I thought would help, but they didn't.

This is a peculiar algorithm, to say the least, since most things can be tuned somewhat. But this is resisting every effort I throw at it...
From my experience, there are two things that affect the effectiveness of LMR:

1. The type of evaluation function.

Thinker has 3 types of eval functions, and I noticed that the more material-oriented eval benefits little from LMR. My guess is that this is because the chances of improving the score with non-captures is smaller.

2. Move ordering of non-captures.

I noticed that if there is no move ordering of non-captures, some good moves can get reduced, or bad moves get searched in full depth. This is no different from doing no LMR at all. You are just at the mercy of the move generator.

In my experience, the non-captures should be sorted in some way, and then LMR would make sense.

Now, because every engine is unique (except for the clones/derivatives/replicates), these findings may not apply to other engines.
The problem is, this is not borne out by testing. I have tried ordering non-captures with a complete static eval, a complete static eval + SEE() of the move being ordered, etc. And I get absolutely no benefit of any kind either in short or long games. I tried both of the above in conjunction with looking at a variable number of early-sorted moves before starting to reduce. In every last case this reduced Elo as the number was increased (which means doing fewer reductions). I even tried the oft-mentioned idea of treating PV vs non-PV nodes differently. Hurt in every case any time I reduce less... The only exceptions I have found is that reducing captures hurts a little, reducing passed pawn pushes hurts almost nothing. Reducing checks is a 15 Elo drop or so (these results are elsewhere in this thread in fact.)
My opinion is that no matter how hard you try to tune some settings it wouldn't produce any noticeable difference when you already have reached the maturity/limit of your search algorithm/design.

I think that in order to have a big leap in playing strength, an engine needs a drastic change in its design. My suggestion is to rewrite the search from scratch and use new ideas. The problem here is what are those new ideas.

I've been tuning LMR in my engine also. Too much reduction and it will search deeper but prone to tactical blunders, too few reductions and you will not benefit from it as it wouldn't result into some extra plies.

By the way, have you tried history pruning from Toga? It seems to be around 40 elo improvement on my old versions before (0.099x versions and below). I haven't tried it in the my new implementation now as I don't use history counters anymore and I don't like the idea of pruning an entire subtree based on search statistics only that might simply contain random numbers in longer time controls.
Daniel Shawul
Posts: 4185
Joined: Tue Mar 14, 2006 11:34 am
Location: Ethiopia

Re: LMR revisited.

Post by Daniel Shawul »

My opinion is that no matter how hard you try to tune some settings it wouldn't produce any noticeable difference when you already have reached the maturity/limit of your search algorithm/design.

I think that in order to have a big leap in playing strength, an engine needs a drastic change in its design. My suggestion is to rewrite the search from scratch and use new ideas. The problem here is what are those new ideas.
I think that one may need to change one 's way of doing selective search from time to time. Aggressive pruning and reductions seem to work better with faster hardware so it might need a revision once in a while but i don't think search needs rewrite that much. I am nowadays being forced to use aggressive prunings I would not consider a while back.
I've been tuning LMR in my engine also. Too much reduction and it will search deeper but prone to tactical blunders, too few reductions and you will not benefit from it as it wouldn't result into some extra plies.

By the way, have you tried history pruning from Toga? It seems to be around 40 elo improvement on my old versions before (0.099x versions and below). I haven't tried it in the my new implementation now as I don't use history counters anymore and I don't like the idea of pruning an entire subtree based on search statistics only that might simply contain random numbers in longer time controls.
The Toga history prunings are something I wanted to test thoroughly even though it looks too risky at first. When I tried them they seem to improve my engine and I don't even use the history information. Just prune away the entire tree (say depth <= 5) starting from move number 7 is what I tried. Many ideas like this might work for an engine short of search depth like mine, for others it might not.

regards,
Daniel
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: LMR revisited.

Post by bob »

Edsel Apostol wrote:
bob wrote:
CThinker wrote:
bob wrote:I have been experimenting with LMR and various ways one might do it more intelligently. And after about 4 weeks of solid testing, I have produced exactly -nothing- that helps. I have tried things from using a complex ordering early in the tree, and then using either one or two "late" counters, one for PV nodes, one for non-PV nodes (ala glaurung). Doesn't help one bit. Just doing the counters without the ordering. nada. I've tried (again) fruit-like history counters. Either no better or much worse depending on the threshold set. I've tried a more localized history counter, like failhi[ply][from-to] and faillo[ply][from-to] so that the values don't get completely scrambled. Again, either no better or worse depending on how those values are used.

I'm still testing, but so far, looking at several programs that do LMR, absolutely none of the ideas I have seen make any difference at all in testing, unless they make the program weaker. I have tested with very fast games, 1+1 games, 5+5 games, and even a few 60+60 tests (those turn into 3 hours + per game, which means I can play about 256 games every 3 hours, which is really too slow to be usable. But I wanted to make sure that the things I was trying were not just tested on very fast games where they might not matter.

I've tested everything in Glaurung 2, fruit 2, toga 2, and a lot of other ideas as well (some given above, not all). This appears to be an idea that either works, or it doesn't. Tuning seems to either hurt or have no impact.

If anyone has any suggestions while I am testing this stuff, feel free to make suggestions. I'd suspect I have tried at least 75% of what will be suggested, but any new ideas are welcome. I've been convinced for a couple of years now that the history-counter approach is simply no good, and I've not been using that for at least that long now. Some of the other ideas I tried I thought would help, but they didn't.

This is a peculiar algorithm, to say the least, since most things can be tuned somewhat. But this is resisting every effort I throw at it...
From my experience, there are two things that affect the effectiveness of LMR:

1. The type of evaluation function.

Thinker has 3 types of eval functions, and I noticed that the more material-oriented eval benefits little from LMR. My guess is that this is because the chances of improving the score with non-captures is smaller.

2. Move ordering of non-captures.

I noticed that if there is no move ordering of non-captures, some good moves can get reduced, or bad moves get searched in full depth. This is no different from doing no LMR at all. You are just at the mercy of the move generator.

In my experience, the non-captures should be sorted in some way, and then LMR would make sense.

Now, because every engine is unique (except for the clones/derivatives/replicates), these findings may not apply to other engines.
The problem is, this is not borne out by testing. I have tried ordering non-captures with a complete static eval, a complete static eval + SEE() of the move being ordered, etc. And I get absolutely no benefit of any kind either in short or long games. I tried both of the above in conjunction with looking at a variable number of early-sorted moves before starting to reduce. In every last case this reduced Elo as the number was increased (which means doing fewer reductions). I even tried the oft-mentioned idea of treating PV vs non-PV nodes differently. Hurt in every case any time I reduce less... The only exceptions I have found is that reducing captures hurts a little, reducing passed pawn pushes hurts almost nothing. Reducing checks is a 15 Elo drop or so (these results are elsewhere in this thread in fact.)
My opinion is that no matter how hard you try to tune some settings it wouldn't produce any noticeable difference when you already have reached the maturity/limit of your search algorithm/design.

I think that in order to have a big leap in playing strength, an engine needs a drastic change in its design. My suggestion is to rewrite the search from scratch and use new ideas. The problem here is what are those new ideas.

I've been tuning LMR in my engine also. Too much reduction and it will search deeper but prone to tactical blunders, too few reductions and you will not benefit from it as it wouldn't result into some extra plies.

By the way, have you tried history pruning from Toga? It seems to be around 40 elo improvement on my old versions before (0.099x versions and below). I haven't tried it in the my new implementation now as I don't use history counters anymore and I don't like the idea of pruning an entire subtree based on search statistics only that might simply contain random numbers in longer time controls.
Yes I have, and it makes _absolutely_ no difference until you start to set the threshold too high and stop reducing most everything. It starts out exactly the same as what I currently do, and slowly gets worse as the threshold for history info blocking reductions goes up and makes it more likely a move will not be reduced...
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: LMR revisited.

Post by bob »

Edsel Apostol wrote:
bob wrote:
CThinker wrote:
bob wrote:I have been experimenting with LMR and various ways one might do it more intelligently. And after about 4 weeks of solid testing, I have produced exactly -nothing- that helps. I have tried things from using a complex ordering early in the tree, and then using either one or two "late" counters, one for PV nodes, one for non-PV nodes (ala glaurung). Doesn't help one bit. Just doing the counters without the ordering. nada. I've tried (again) fruit-like history counters. Either no better or much worse depending on the threshold set. I've tried a more localized history counter, like failhi[ply][from-to] and faillo[ply][from-to] so that the values don't get completely scrambled. Again, either no better or worse depending on how those values are used.

I'm still testing, but so far, looking at several programs that do LMR, absolutely none of the ideas I have seen make any difference at all in testing, unless they make the program weaker. I have tested with very fast games, 1+1 games, 5+5 games, and even a few 60+60 tests (those turn into 3 hours + per game, which means I can play about 256 games every 3 hours, which is really too slow to be usable. But I wanted to make sure that the things I was trying were not just tested on very fast games where they might not matter.

I've tested everything in Glaurung 2, fruit 2, toga 2, and a lot of other ideas as well (some given above, not all). This appears to be an idea that either works, or it doesn't. Tuning seems to either hurt or have no impact.

If anyone has any suggestions while I am testing this stuff, feel free to make suggestions. I'd suspect I have tried at least 75% of what will be suggested, but any new ideas are welcome. I've been convinced for a couple of years now that the history-counter approach is simply no good, and I've not been using that for at least that long now. Some of the other ideas I tried I thought would help, but they didn't.

This is a peculiar algorithm, to say the least, since most things can be tuned somewhat. But this is resisting every effort I throw at it...
From my experience, there are two things that affect the effectiveness of LMR:

1. The type of evaluation function.

Thinker has 3 types of eval functions, and I noticed that the more material-oriented eval benefits little from LMR. My guess is that this is because the chances of improving the score with non-captures is smaller.

2. Move ordering of non-captures.

I noticed that if there is no move ordering of non-captures, some good moves can get reduced, or bad moves get searched in full depth. This is no different from doing no LMR at all. You are just at the mercy of the move generator.

In my experience, the non-captures should be sorted in some way, and then LMR would make sense.

Now, because every engine is unique (except for the clones/derivatives/replicates), these findings may not apply to other engines.
The problem is, this is not borne out by testing. I have tried ordering non-captures with a complete static eval, a complete static eval + SEE() of the move being ordered, etc. And I get absolutely no benefit of any kind either in short or long games. I tried both of the above in conjunction with looking at a variable number of early-sorted moves before starting to reduce. In every last case this reduced Elo as the number was increased (which means doing fewer reductions). I even tried the oft-mentioned idea of treating PV vs non-PV nodes differently. Hurt in every case any time I reduce less... The only exceptions I have found is that reducing captures hurts a little, reducing passed pawn pushes hurts almost nothing. Reducing checks is a 15 Elo drop or so (these results are elsewhere in this thread in fact.)
My opinion is that no matter how hard you try to tune some settings it wouldn't produce any noticeable difference when you already have reached the maturity/limit of your search algorithm/design.

I think that in order to have a big leap in playing strength, an engine needs a drastic change in its design. My suggestion is to rewrite the search from scratch and use new ideas. The problem here is what are those new ideas.

I've been tuning LMR in my engine also. Too much reduction and it will search deeper but prone to tactical blunders, too few reductions and you will not benefit from it as it wouldn't result into some extra plies.

By the way, have you tried history pruning from Toga? It seems to be around 40 elo improvement on my old versions before (0.099x versions and below). I haven't tried it in the my new implementation now as I don't use history counters anymore and I don't like the idea of pruning an entire subtree based on search statistics only that might simply contain random numbers in longer time controls.
Yes I have, and it makes _absolutely_ no difference until you start to set the threshold too high and stop reducing most everything. It starts out exactly the same as what I currently do, and slowly gets worse as the threshold for history info blocking reductions goes up and makes it more likely a move will not be reduced...

wait. You mean the history pruning, not history-tweaked LMR as is done in fruit/toga. No, I have not yet tried that. It is on my list, but not until I try to exhaust all LMR improvement ideas...
Edsel Apostol
Posts: 803
Joined: Mon Jul 17, 2006 5:53 am
Full name: Edsel Apostol

Re: LMR revisited.

Post by Edsel Apostol »

bob wrote:
Edsel Apostol wrote:
bob wrote:
CThinker wrote:
bob wrote:I have been experimenting with LMR and various ways one might do it more intelligently. And after about 4 weeks of solid testing, I have produced exactly -nothing- that helps. I have tried things from using a complex ordering early in the tree, and then using either one or two "late" counters, one for PV nodes, one for non-PV nodes (ala glaurung). Doesn't help one bit. Just doing the counters without the ordering. nada. I've tried (again) fruit-like history counters. Either no better or much worse depending on the threshold set. I've tried a more localized history counter, like failhi[ply][from-to] and faillo[ply][from-to] so that the values don't get completely scrambled. Again, either no better or worse depending on how those values are used.

I'm still testing, but so far, looking at several programs that do LMR, absolutely none of the ideas I have seen make any difference at all in testing, unless they make the program weaker. I have tested with very fast games, 1+1 games, 5+5 games, and even a few 60+60 tests (those turn into 3 hours + per game, which means I can play about 256 games every 3 hours, which is really too slow to be usable. But I wanted to make sure that the things I was trying were not just tested on very fast games where they might not matter.

I've tested everything in Glaurung 2, fruit 2, toga 2, and a lot of other ideas as well (some given above, not all). This appears to be an idea that either works, or it doesn't. Tuning seems to either hurt or have no impact.

If anyone has any suggestions while I am testing this stuff, feel free to make suggestions. I'd suspect I have tried at least 75% of what will be suggested, but any new ideas are welcome. I've been convinced for a couple of years now that the history-counter approach is simply no good, and I've not been using that for at least that long now. Some of the other ideas I tried I thought would help, but they didn't.

This is a peculiar algorithm, to say the least, since most things can be tuned somewhat. But this is resisting every effort I throw at it...
From my experience, there are two things that affect the effectiveness of LMR:

1. The type of evaluation function.

Thinker has 3 types of eval functions, and I noticed that the more material-oriented eval benefits little from LMR. My guess is that this is because the chances of improving the score with non-captures is smaller.

2. Move ordering of non-captures.

I noticed that if there is no move ordering of non-captures, some good moves can get reduced, or bad moves get searched in full depth. This is no different from doing no LMR at all. You are just at the mercy of the move generator.

In my experience, the non-captures should be sorted in some way, and then LMR would make sense.

Now, because every engine is unique (except for the clones/derivatives/replicates), these findings may not apply to other engines.
The problem is, this is not borne out by testing. I have tried ordering non-captures with a complete static eval, a complete static eval + SEE() of the move being ordered, etc. And I get absolutely no benefit of any kind either in short or long games. I tried both of the above in conjunction with looking at a variable number of early-sorted moves before starting to reduce. In every last case this reduced Elo as the number was increased (which means doing fewer reductions). I even tried the oft-mentioned idea of treating PV vs non-PV nodes differently. Hurt in every case any time I reduce less... The only exceptions I have found is that reducing captures hurts a little, reducing passed pawn pushes hurts almost nothing. Reducing checks is a 15 Elo drop or so (these results are elsewhere in this thread in fact.)
My opinion is that no matter how hard you try to tune some settings it wouldn't produce any noticeable difference when you already have reached the maturity/limit of your search algorithm/design.

I think that in order to have a big leap in playing strength, an engine needs a drastic change in its design. My suggestion is to rewrite the search from scratch and use new ideas. The problem here is what are those new ideas.

I've been tuning LMR in my engine also. Too much reduction and it will search deeper but prone to tactical blunders, too few reductions and you will not benefit from it as it wouldn't result into some extra plies.

By the way, have you tried history pruning from Toga? It seems to be around 40 elo improvement on my old versions before (0.099x versions and below). I haven't tried it in the my new implementation now as I don't use history counters anymore and I don't like the idea of pruning an entire subtree based on search statistics only that might simply contain random numbers in longer time controls.
Yes I have, and it makes _absolutely_ no difference until you start to set the threshold too high and stop reducing most everything. It starts out exactly the same as what I currently do, and slowly gets worse as the threshold for history info blocking reductions goes up and makes it more likely a move will not be reduced...

wait. You mean the history pruning, not history-tweaked LMR as is done in fruit/toga. No, I have not yet tried that. It is on my list, but not until I try to exhaust all LMR improvement ideas...
Yes, I mean History Pruning where it prunes an entire subtree, not just reduce it. I'm interested to know if it proves better for Crafty as I'm wondering why it seems to be counter intuitive and yet it works well with Toga.

I have some ideas in LMR that seems to work well with my engine resulting to deeper search but I don't know if it's applicable to other engines. It's just a simple idea but it's hard to tune as there are a lot of combinations of settings involve and I don't have the resources to test them all.