소스 검색

More concise commentary in planner.cpp

Scott Lahteine 6 년 전
부모
커밋
8f14ef855d
1개의 변경된 파일85개의 추가작업 그리고 145개의 파일을 삭제
  1. 85
    145
      Marlin/src/module/planner.cpp

+ 85
- 145
Marlin/src/module/planner.cpp 파일 보기

@@ -235,145 +235,86 @@ void Planner::init() {
235 235
 #if ENABLED(S_CURVE_ACCELERATION)
236 236
 
237 237
   #ifdef __AVR__
238
-    // This routine, for AVR, returns 0x1000000 / d, but trying to get the inverse as
239
-    //  fast as possible. A fast converging iterative Newton-Raphson method is able to
240
-    //  reach full precision in just 1 iteration, and takes 211 cycles (worst case, mean
241
-    //  case is less, up to 30 cycles for small divisors), instead of the 500 cycles a
242
-    //  normal division would take.
243
-    //
244
-    // Inspired by the following page,
245
-    //  https://stackoverflow.com/questions/27801397/newton-raphson-division-with-big-integers
246
-    //
247
-    // Suppose we want to calculate
248
-    //  floor(2 ^ k / B)    where B is a positive integer
249
-    // Then
250
-    //  B must be <= 2^k, otherwise, the quotient is 0.
251
-    //
252
-    // The Newton - Raphson iteration for x = B / 2 ^ k yields:
253
-    //  q[n + 1] = q[n] * (2 - q[n] * B / 2 ^ k)
254
-    //
255
-    // We can rearrange it as:
256
-    //  q[n + 1] = q[n] * (2 ^ (k + 1) - q[n] * B) >> k
257
-    //
258
-    //  Each iteration of this kind requires only integer multiplications
259
-    // and bit shifts.
260
-    //  Does it converge to floor(2 ^ k / B) ?:  Not necessarily, but, in
261
-    // the worst case, it eventually alternates between floor(2 ^ k / B)
262
-    // and ceiling(2 ^ k / B)).
263
-    //  So we can use some not-so-clever test to see if we are in this
264
-    // case, and extract floor(2 ^ k / B).
265
-    //  Lastly, a simple but important optimization for this approach is to
266
-    // truncate multiplications (i.e.calculate only the higher bits of the
267
-    // product) in the early iterations of the Newton - Raphson method.The
268
-    // reason to do so, is that the results of the early iterations are far
269
-    // from the quotient, and it doesn't matter to perform them inaccurately.
270
-    //  Finally, we should pick a good starting value for x. Knowing how many
271
-    // digits the divisor has, we can estimate it:
272
-    //
273
-    // 2^k / x = 2 ^ log2(2^k / x)
274
-    // 2^k / x = 2 ^(log2(2^k)-log2(x))
275
-    // 2^k / x = 2 ^(k*log2(2)-log2(x))
276
-    // 2^k / x = 2 ^ (k-log2(x))
277
-    // 2^k / x >= 2 ^ (k-floor(log2(x)))
278
-    // floor(log2(x)) simply is the index of the most significant bit set.
279
-    //
280
-    //  If we could improve this estimation even further, then the number of
281
-    // iterations can be dropped quite a bit, thus saving valuable execution time.
282
-    //  The paper "Software Integer Division" by Thomas L.Rodeheffer, Microsoft
283
-    // Research, Silicon Valley,August 26, 2008, that is available at
284
-    // https://www.microsoft.com/en-us/research/wp-content/uploads/2008/08/tr-2008-141.pdf
285
-    // suggests , for its integer division algorithm, that using a table to supply the
286
-    // first 8 bits of precision, and due to the quadratic convergence nature of the
287
-    // Newton-Raphon iteration, then just 2 iterations should be enough to get
288
-    // maximum precision of the division.
289
-    //  If we precompute values of inverses for small denominator values, then
290
-    // just one Newton-Raphson iteration is enough to reach full precision
291
-    //  We will use the top 9 bits of the denominator as index.
292
-    //
293
-    //  The AVR assembly function is implementing the following C code, included
294
-    // here as reference:
295
-    //
296
-    // uint32_t get_period_inverse(uint32_t d) {
297
-    //  static const uint8_t inv_tab[256] = {
298
-    //    255,253,252,250,248,246,244,242,240,238,236,234,233,231,229,227,
299
-    //    225,224,222,220,218,217,215,213,212,210,208,207,205,203,202,200,
300
-    //    199,197,195,194,192,191,189,188,186,185,183,182,180,179,178,176,
301
-    //    175,173,172,170,169,168,166,165,164,162,161,160,158,157,156,154,
302
-    //    153,152,151,149,148,147,146,144,143,142,141,139,138,137,136,135,
303
-    //    134,132,131,130,129,128,127,126,125,123,122,121,120,119,118,117,
304
-    //    116,115,114,113,112,111,110,109,108,107,106,105,104,103,102,101,
305
-    //    100,99,98,97,96,95,94,93,92,91,90,89,88,88,87,86,
306
-    //    85,84,83,82,81,80,80,79,78,77,76,75,74,74,73,72,
307
-    //    71,70,70,69,68,67,66,66,65,64,63,62,62,61,60,59,
308
-    //    59,58,57,56,56,55,54,53,53,52,51,50,50,49,48,48,
309
-    //    47,46,46,45,44,43,43,42,41,41,40,39,39,38,37,37,
310
-    //    36,35,35,34,33,33,32,32,31,30,30,29,28,28,27,27,
311
-    //    26,25,25,24,24,23,22,22,21,21,20,19,19,18,18,17,
312
-    //    17,16,15,15,14,14,13,13,12,12,11,10,10,9,9,8,
313
-    //    8,7,7,6,6,5,5,4,4,3,3,2,2,1,0,0
314
-    //  };
315
-    //
316
-    //  // For small denominators, it is cheaper to directly store the result,
317
-    //  //  because those denominators would require 2 Newton-Raphson iterations
318
-    //  //  to converge to the required result precision. For bigger ones, just
319
-    //  //  ONE Newton-Raphson iteration is enough to get maximum precision!
320
-    //  static const uint32_t small_inv_tab[111] PROGMEM = {
321
-    //    16777216,16777216,8388608,5592405,4194304,3355443,2796202,2396745,2097152,1864135,1677721,1525201,1398101,1290555,1198372,1118481,
322
-    //    1048576,986895,932067,883011,838860,798915,762600,729444,699050,671088,645277,621378,599186,578524,559240,541200,
323
-    //    524288,508400,493447,479349,466033,453438,441505,430185,419430,409200,399457,390167,381300,372827,364722,356962,
324
-    //    349525,342392,335544,328965,322638,316551,310689,305040,299593,294337,289262,284359,279620,275036,270600,266305,
325
-    //    262144,258111,254200,250406,246723,243148,239674,236298,233016,229824,226719,223696,220752,217885,215092,212369,
326
-    //    209715,207126,204600,202135,199728,197379,195083,192841,190650,188508,186413,184365,182361,180400,178481,176602,
327
-    //    174762,172960,171196,169466,167772,166111,164482,162885,161319,159783,158275,156796,155344,153919,152520
328
-    //  };
329
-    //
330
-    //  // For small divisors, it is best to directly retrieve the results
331
-    //  if (d <= 110)
332
-    //    return pgm_read_dword(&small_inv_tab[d]);
333
-    //
334
-    //  // Compute initial estimation of 0x1000000/x -
335
-    //  // Get most significant bit set on divider
336
-    //  uint8_t idx = 0;
337
-    //  uint32_t nr = d;
338
-    //  if (!(nr & 0xFF0000)) {
339
-    //    nr <<= 8;
340
-    //    idx += 8;
341
-    //    if (!(nr & 0xFF0000)) {
342
-    //      nr <<= 8;
343
-    //      idx += 8;
344
-    //    }
345
-    //  }
346
-    //  if (!(nr & 0xF00000)) {
347
-    //    nr <<= 4;
348
-    //    idx += 4;
349
-    //  }
350
-    //  if (!(nr & 0xC00000)) {
351
-    //    nr <<= 2;
352
-    //    idx += 2;
353
-    //  }
354
-    //  if (!(nr & 0x800000)) {
355
-    //    nr <<= 1;
356
-    //    idx += 1;
357
-    //  }
358
-    //
359
-    //  // Isolate top 9 bits of the denominator, to be used as index into the initial estimation table
360
-    //  uint32_t tidx = nr >> 15;         // top 9 bits. bit8 is always set
361
-    //  uint32_t ie = inv_tab[tidx & 0xFF] + 256; // Get the table value. bit9 is always set
362
-    //  uint32_t x = idx <= 8 ? (ie >> (8 - idx)) : (ie << (idx - 8)); // Position the estimation at the proper place
363
-    //
364
-    //  // Now, refine estimation by newton-raphson. 1 iteration is enough
365
-    //  x = uint32_t((x * uint64_t((1 << 25) - x * d)) >> 24);
366
-    //
367
-    //  // Estimate remainder
368
-    //  uint32_t r = (1 << 24) - x * d;
369
-    //
370
-    //  // Check if we must adjust result
371
-    //  if (r >= d) x++;
372
-    //
373
-    //  // x holds the proper estimation
374
-    //  return uint32_t(x);
375
-    // }
376
-    //
238
+    /**
239
+     * This routine returns 0x1000000 / d, getting the inverse as fast as possible.
240
+     * A fast-converging iterative Newton-Raphson method can reach full precision in
241
+     * just 1 iteration, and takes 211 cycles (worst case; the mean case is less, up
242
+     * to 30 cycles for small divisors), instead of the 500 cycles a normal division
243
+     * would take.
244
+     *
245
+     * Inspired by the following page:
246
+     *  https://stackoverflow.com/questions/27801397/newton-raphson-division-with-big-integers
247
+     *
248
+     * Suppose we want to calculate  floor(2 ^ k / B)  where B is a positive integer
249
+     * Then, B must be <= 2^k, otherwise, the quotient is 0.
250
+     *
251
+     * The Newton - Raphson iteration for x = B / 2 ^ k yields:
252
+     *  q[n + 1] = q[n] * (2 - q[n] * B / 2 ^ k)
253
+     *
254
+     * This can be rearranged to:
255
+     *  q[n + 1] = q[n] * (2 ^ (k + 1) - q[n] * B) >> k
256
+     *
257
+     * Each iteration requires only integer multiplications and bit shifts.
258
+     * It doesn't necessarily converge to floor(2 ^ k / B) but in the worst case
259
+     * it eventually alternates between floor(2 ^ k / B) and ceil(2 ^ k / B).
260
+     * So it checks for this case and extracts floor(2 ^ k / B).
261
+     *
262
+     * A simple but important optimization for this approach is to truncate
263
+     * multiplications (i.e., calculate only the higher bits of the product) in the
264
+     * early iterations of the Newton - Raphson method. This is done so the results
265
+     * of the early iterations are far from the quotient. Then it doesn't matter if
266
+     * they are done inaccurately.
267
+     * It's important to pick a good starting value for x. Knowing how many
268
+     * digits the divisor has, it can be estimated:
269
+     *
270
+     *   2^k / x = 2 ^ log2(2^k / x)
271
+     *   2^k / x = 2 ^(log2(2^k)-log2(x))
272
+     *   2^k / x = 2 ^(k*log2(2)-log2(x))
273
+     *   2^k / x = 2 ^ (k-log2(x))
274
+     *   2^k / x >= 2 ^ (k-floor(log2(x)))
275
+     *   floor(log2(x)) is simply the index of the most significant bit set.
276
+     *
277
+     * If this estimation can be improved even further the number of iterations can be
278
+     * reduced a lot, saving valuable execution time.
279
+     * The paper "Software Integer Division" by Thomas L.Rodeheffer, Microsoft
280
+     * Research, Silicon Valley,August 26, 2008, available at
281
+     * https://www.microsoft.com/en-us/research/wp-content/uploads/2008/08/tr-2008-141.pdf
282
+     * suggests, for its integer division algorithm, using a table to supply the first
283
+     * 8 bits of precision, then, due to the quadratic convergence nature of the
284
+     * Newton-Raphon iteration, just 2 iterations should be enough to get maximum
285
+     * precision of the division.
286
+     * By precomputing values of inverses for small denominator values, just one
287
+     * Newton-Raphson iteration is enough to reach full precision.
288
+     * This code uses the top 9 bits of the denominator as index.
289
+     *
290
+     * The AVR assembly function implements this C code using the data below:
291
+     *
292
+     *  // For small divisors, it is best to directly retrieve the results
293
+     *  if (d <= 110) return pgm_read_dword(&small_inv_tab[d]);
294
+     *
295
+     *  // Compute initial estimation of 0x1000000/x -
296
+     *  // Get most significant bit set on divider
297
+     *  uint8_t idx = 0;
298
+     *  uint32_t nr = d;
299
+     *  if (!(nr & 0xFF0000)) {
300
+     *    nr <<= 8; idx += 8;
301
+     *    if (!(nr & 0xFF0000)) { nr <<= 8; idx += 8; }
302
+     *  }
303
+     *  if (!(nr & 0xF00000)) { nr <<= 4; idx += 4; }
304
+     *  if (!(nr & 0xC00000)) { nr <<= 2; idx += 2; }
305
+     *  if (!(nr & 0x800000)) { nr <<= 1; idx += 1; }
306
+     *
307
+     *  // Isolate top 9 bits of the denominator, to be used as index into the initial estimation table
308
+     *  uint32_t tidx = nr >> 15,                                       // top 9 bits. bit8 is always set
309
+     *           ie = inv_tab[tidx & 0xFF] + 256,                       // Get the table value. bit9 is always set
310
+     *           x = idx <= 8 ? (ie >> (8 - idx)) : (ie << (idx - 8));  // Position the estimation at the proper place
311
+     *
312
+     *  x = uint32_t((x * uint64_t(_BV(25) - x * d)) >> 24);            // Refine estimation by newton-raphson. 1 iteration is enough
313
+     *  const uint32_t r = _BV(24) - x * d;                             // Estimate remainder
314
+     *  if (r >= d) x++;                                                // Check whether to adjust result
315
+     *  return uint32_t(x);                                             // x holds the proper estimation
316
+     *
317
+     */
377 318
     static uint32_t get_period_inverse(uint32_t d) {
378 319
 
379 320
       static const uint8_t inv_tab[256] PROGMEM = {
@@ -409,13 +350,12 @@ void Planner::init() {
409 350
       };
410 351
 
411 352
       // For small divisors, it is best to directly retrieve the results
412
-      if (d <= 110)
413
-        return pgm_read_dword(&small_inv_tab[d]);
353
+      if (d <= 110) return pgm_read_dword(&small_inv_tab[d]);
414 354
 
415
-      register uint8_t r8 = d & 0xFF;
416
-      register uint8_t r9 = (d >> 8) & 0xFF;
417
-      register uint8_t r10 = (d >> 16) & 0xFF;
418
-      register uint8_t r2,r3,r4,r5,r6,r7,r11,r12,r13,r14,r15,r16,r17,r18;
355
+      register uint8_t r8 = d & 0xFF,
356
+                       r9 = (d >> 8) & 0xFF,
357
+                       r10 = (d >> 16) & 0xFF,
358
+                       r2,r3,r4,r5,r6,r7,r11,r12,r13,r14,r15,r16,r17,r18;
419 359
       register const uint8_t* ptab = inv_tab;
420 360
 
421 361
       __asm__ __volatile__(

Loading…
취소
저장