range behaviour

via Digitalmars-d digitalmars-d at puremagic.com
Fri May 16 08:44:58 PDT 2014


On Thursday, 15 May 2014 at 13:10:29 UTC, Dicebot wrote:
> If compiler lacks contextual knowledge, than only means that 
> range is not actually semantically equivalent to a loop.

Not really. Here is a simple example, a sawtooth generator that 
goes from 1 to 0 with a cycle length >=2 (nyquist).

import std.algorithm;
import std.math;

struct gen_sawtooth {
   enum bool empty = false;
   float front;
   float delta;

   this(immutable float samps_per_cycle){
      front = 1.0f;
      delta = 1.0f/samps_per_cycle;
   }

   void popFront() {
     front -= delta;
     if(front < 0.0f) front += 1.0f;
   }
}

void rangefill_sawtooth(float[]	a, immutable float 
samps_per_cycle){
    auto gen = gen_sawtooth(samps_per_cycle);
    fill(a,gen);
}

void fill_sawtooth(float[] a,immutable float samps_per_cycle) {
   if(a.length==0) return;

   immutable float delta = 1.0f/samps_per_cycle;
   immutable max_cycle_length = 
cast(uint)floor(samps_per_cycle*1.0001+1);
   immutable lastcycle = a.length - max_cycle_length;

   float v = 1.0f;
   uint i = 0;

   do {
     do{ // main inner loop
       a[i] = v;
       ++i;
       v -= delta;
     } while(v>=0.0f);
     v += 1.0f;
   } while( i < lastcycle );

   for(;i<a.length;++i){ // can be optimized further
     a[i] = v;
     v -= delta;
     if (v<0.0f) v += 1.0f;
   }
}


The generated code for the range based version does not create a 
fast innerloop, it lacks enough context and smarts:

fill_sawtooth main inner loop:

loop:
         incl    %eax
	leal    -2(%rax), %edx
         movss   %xmm1, (%rbx,%rdx,4)
         subss   %xmm0, %xmm1
         ucomiss %xmm3, %xmm1
         jae     loop


rangefill_sawtooth inner loop:

loop:
         movss   %xmm3, (%rsi)
         subss   %xmm2, %xmm3
         decq    %rdi
         ucomiss %xmm3, %xmm0
         jbe     skip
         addss   %xmm1, %xmm3
skip:
         addq    $4, %rsi
         testq   %rdi, %rdi
         jne     loop


> What is wrong is assumption that such kinds of loops are 
> anything but tiny minority and this warrants generic "ranges 
> can never be as fast as loops" statement.

Not without significant work…

>> Floating point math is inaccurate, that means the compiler 
>> will have to guess what kind of accuracy you are happy with…
>
> AFAIK it is actually not true. Floating point standard defines 
> basic precision guarantees

Minimum yes. That makes drift unpredictable. Sometimes you care 
more about deltas than absolute values.


More information about the Digitalmars-d mailing list