May 16, 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.
1 2 3
Next ›   Last »