Re: Compiler magic for preventing memory access re-ordering _by the compiler_ (keywords: memory model, compiler optimisations, memory order)

2017-11-05 Thread Michael V. Franklin via Digitalmars-d-learn
On Monday, 6 November 2017 at 05:54:00 UTC, Michael V. Franklin 
wrote:

On Monday, 6 November 2017 at 03:40:23 UTC, Cecil Ward wrote:


Is there a magic visible sign (or even one needed) in the D 
language that tells D _compilers_ not to move certain types of 
memory load / store operations forwards or backwards relative 
to other operations when optimising the code so that the order 
in the actual generated code varies from the source code order?


You may be looking for volatileLoad/Store:  
https://dlang.org/changelog/2.067.0.html#volatile-load-store


Also https://dlang.org/phobos/core_bitop.html#.volatileLoad

Mike




Re: Compiler magic for preventing memory access re-ordering _by the compiler_ (keywords: memory model, compiler optimisations, memory order)

2017-11-05 Thread Michael V. Franklin via Digitalmars-d-learn

On Monday, 6 November 2017 at 03:40:23 UTC, Cecil Ward wrote:


Is there a magic visible sign (or even one needed) in the D 
language that tells D _compilers_ not to move certain types of 
memory load / store operations forwards or backwards relative 
to other operations when optimising the code so that the order 
in the actual generated code varies from the source code order?


You may be looking for volatileLoad/Store:  
https://dlang.org/changelog/2.067.0.html#volatile-load-store


Mike


Compiler magic for preventing memory access re-ordering _by the compiler_ (keywords: memory model, compiler optimisations, memory order)

2017-11-05 Thread Cecil Ward via Digitalmars-d-learn
I have to apologise in advance for a truly dumb question, so 
please be kind.


Is there a magic visible sign (or even one needed) in the D 
language that tells D _compilers_ not to move certain types of 
memory load / store operations forwards or backwards relative to 
other operations when optimising the code so that the order in 
the actual generated code varies from the source code order?


I see the various routines available in the runtime library that 
can generate various sorts of special instructions on CPU x, 
hardware fences/barriers etc. That's not what I'm asking about 
tho. I'm just wondering about how the compilers know how much 
freedom they are allowed in moving stuff forwards/backwards or 
even deleting stupid wasteful memory operations altogether, and 
whether there are any special things that a compiler writer needs 
to spot as being magic in D source code.


If the answer is 'no'/'none', I suppose it could be in part down 
to the fact that the _implementation_ of certain D features by 
compilers make use of various compiler-specific non-D magic 
facilities that a compiler already has anyway due to its modern 
C-implementation heritage? But I don't feel that I've answered my 
question in this way, if a compiler is generally free to re-order 
certain statements or external calls past other external calls or 
special statements. That's a general statement of my ignorance 
about the limits of compilers’ freedom in optimising code, and 
something I urgently need to correct. :-) A completely general 
question, which I should have found an answer to first. (Again, 
please be nice to a poor fool.)


This could be a non-question for all I know, so do forgive my 
ignorance. If calls to certain types of _routines_ whose content 
is not know can not be re-ordered either simply (a) because their 
effects are unknown, or (b) because 'volatile' type declarations 
are used in the implementation, is that merely how things happen 
to work? One further dumb question relating to this: if this is 
meaningful and the answer is case (a) could inlining stuff copied 
out of the runtime library into your own routines then wreck the 
safety, and could LTO-type highly clever whole-program 
optimisation undo safety similarly?


Re: problem with multiwayMerge and chunkBy

2017-11-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 5 November 2017 at 22:47:10 UTC, Nicholas Wilson wrote:

f.multiwayMerge.chunks(128).joiner.chunkBy!(pred).writeln;

since it seems to be the iteration that stuff things up and 
this changes it.


If that doesn't work you could try rolling your own version of 
chunk with `take` and a static array.


Re: problem with multiwayMerge and chunkBy

2017-11-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 5 November 2017 at 13:32:57 UTC, Matthew Gamble wrote:
On Sunday, 5 November 2017 at 03:21:06 UTC, Nicholas Wilson 
wrote:
On Saturday, 4 November 2017 at 18:57:17 UTC, Matthew Gamble 
wrote:

[...]


It should, this looks like a bug somewhere, please file one at 
issues.dlang.org/ .


in the mean time

struct Replicate(T)
{
Tuple!(T, uint) e;
@property bool empty() { return e[1] == 0 ; }
@property auto front() {return e[0]; }
void popFront() { --e[1]; }
}

Replicate!T replicate(T)(Tuple!(T, uint) e)
{
return typeof(return)(e);
}

f.multiwayMerge.group!"a == b".map!(replicate).writeln;

Does the same thing provided your predicate is "a == b".



Thanks Nicholas.
I posted the bug as you suggested. My predicate is not quite a 
== b, otherwise I would never have needed chunkBy in the first 
place. But thanks, I'm pursuing a workaround.


Matt


One thing you might try is instead of using .array to eagerly 
evaluate the whole range, eagerly evaluate only a part (say 128 
elements) and .joiner them.


import std.range : chunks;

f.multiwayMerge.chunks(128).joiner.chunkBy!(pred).writeln;

since it seems to be the iteration that stuff things up and this 
changes it.


Creating a C# like Asynchronous Socket

2017-11-05 Thread DrCataclysm via Digitalmars-d-learn
I am trying to build something like the asynchronous Sockets from 
C# .NET but I'm stuck at the accepting phase.


My code is something like this:


public class TCPListener {

ushort _port;
string _address;
bool _active;
string _lineEnd;
ubyte[] _messageBuffer;
Socket _socket;
Socket _connection;
int _waitForAnswer = 500;
bool _keepOpen = true;

this(string address, ushort port, string lineEnd = "\n") {
_port = port;
_address = address;
_socket = new TcpSocket();
_socket.setOption(SocketOptionLevel.SOCKET, 
SocketOption.REUSEADDR, true);

this.connect();
this.connect();
}

void startListening(){
try{
_socket.bind(new InternetAddress(_port));
_socket.listen(3);
}
catch (Exception e){
writeln(e.msg);
}
auto _connectionTask = task();
_connectionTask.executeInNewThread();
}

private void Accept(){
bool error = false;
// try to accept connection
try{
Socket client = _socket.accept();
Thread.sleep( dur!("msecs")( 50 ) );
MessageBuffer buffer;
auto received = client.receive(buffer.data);
emit(error);
//_connection = client;
}
catch (SocketAcceptException e){
writeln("Error while accepting connection: " ~ e.msg);
error = true;
}public class TCPListener {

ushort _port;
string _address;
bool _active;
string _lineEnd;
ubyte[] _messageBuffer;
Socket _socket;
Socket _connection;
int _waitForAnswer = 500;
bool _keepOpen = true;

this(string address, ushort port, string lineEnd = "\n") {
_port = port;
_address = address;
_socket = new TcpSocket();
_socket.setOption(SocketOptionLevel.SOCKET, 
SocketOption.REUSEADDR, true);

this.connect();
this.connect();
}

void startListening(){
try{
_socket.bind(new InternetAddress(_port));
_socket.listen(3);
}
catch (Exception e){
writeln(e.msg);
}
auto _connectionTask = task();
_connectionTask.executeInNewThread();
}

private void Accept(){
bool error = false;
// try to accept connection
try{
Socket client = _socket.accept();
Thread.sleep( dur!("msecs")( 50 ) );
MessageBuffer buffer;
auto received = client.receive(buffer.data);
emit(error);
//_connection = client;
}
catch (SocketAcceptException e){
writeln("Error while accepting connection: " ~ e.msg);
error = true;
}
finally{
emit(error);
}
}

mixin Signal!(bool);

finally{
emit(error);
}
}

mixin Signal!(bool);

...
}


The client created by _socket.accept() cannot receive any data.

client.receive() immediately returns 0 like a non-blocking 
socket. I think it has something to do with the original socket 
being owned by a different thread.


I am not very familiar with multitasking/multithreading in D so 
any help would be appreciated.


Re: Strange AV in asm mode (code only for amd64)

2017-11-05 Thread user1234 via Digitalmars-d-learn

On Sunday, 5 November 2017 at 14:27:18 UTC, Eugene Wissner wrote:

On Sunday, 5 November 2017 at 13:43:15 UTC, user1234 wrote:

[...]


One of the problems is that "naked" is missing in your 
assembly. If you write


asm pure nothrow
{
 naked;
 mov RAX, 1;
 ret;
 nop;nop;nop;nop;nop;nop;nop;
 mov RAX, 2;
 ret;
}

writeln(proc1()) works. Without "naked" dmd generates the 
prologue and epilogue for your function. Inside the assembly 
you return from the function without restoring the stack. It 
causes the segfault. So you have to write the prologue before 
returning or use nacked assembly.
With "naked" and "Proc proc2 = cast(Proc) (cast(void*)proc1 + 
8);" the example works.


Yeah thanks, i figured it out too. Also there was too much nops.


Re: Strange AV in asm mode (code only for amd64)

2017-11-05 Thread user1234 via Digitalmars-d-learn

On Sunday, 5 November 2017 at 13:43:15 UTC, user1234 wrote:

[...]


Hmmm it was just the amount of nops.

---
import std.stdio;

alias Proc = size_t function();

size_t allInnOne()
{
asm pure nothrow
{
naked;
mov RAX, 1;
ret;
nop;nop;
mov RAX, 2;
ret;
}
}

void main()
{
Proc proc1 = 
Proc proc2 = cast(Proc) (cast(void*) + 8);
writeln(proc1(), " ",proc2());
}
---



Re: Strange AV in asm mode (code only for amd64)

2017-11-05 Thread Eugene Wissner via Digitalmars-d-learn

On Sunday, 5 November 2017 at 13:43:15 UTC, user1234 wrote:

Hello, try this:

---
import std.stdio;

alias Proc = size_t function();

size_t allInnOne()
{
asm pure nothrow
{
mov RAX, 1;
ret;
nop;nop;nop;nop;nop;nop;nop;
mov RAX, 2;
ret;
}
}

void main()
{
Proc proc1 = 
Proc proc2 = cast(Proc) (cast(void*)proc1 + 16);
writeln(proc1(), " ", proc2());
}
---

The call to proc1() gens a SEGFAULT after the first RET.
Remove the call to proc1() and it works.

Why that ?


One of the problems is that "naked" is missing in your assembly. 
If you write


asm pure nothrow
{
 naked;
 mov RAX, 1;
 ret;
 nop;nop;nop;nop;nop;nop;nop;
 mov RAX, 2;
 ret;
}

writeln(proc1()) works. Without "naked" dmd generates the 
prologue and epilogue for your function. Inside the assembly you 
return from the function without restoring the stack. It causes 
the segfault. So you have to write the prologue before returning 
or use nacked assembly.
With "naked" and "Proc proc2 = cast(Proc) (cast(void*)proc1 + 
8);" the example works.


Strange AV in asm mode (code only for amd64)

2017-11-05 Thread user1234 via Digitalmars-d-learn

Hello, try this:

---
import std.stdio;

alias Proc = size_t function();

size_t allInnOne()
{
asm pure nothrow
{
mov RAX, 1;
ret;
nop;nop;nop;nop;nop;nop;nop;
mov RAX, 2;
ret;
}
}

void main()
{
Proc proc1 = 
Proc proc2 = cast(Proc) (cast(void*)proc1 + 16);
writeln(proc1(), " ", proc2());
}
---

The call to proc1() gens a SEGFAULT after the first RET.
Remove the call to proc1() and it works.

Why that ?


Re: problem with multiwayMerge and chunkBy

2017-11-05 Thread Matthew Gamble via Digitalmars-d-learn

On Sunday, 5 November 2017 at 03:21:06 UTC, Nicholas Wilson wrote:
On Saturday, 4 November 2017 at 18:57:17 UTC, Matthew Gamble 
wrote:

[...]


It should, this looks like a bug somewhere, please file one at 
issues.dlang.org/ .


in the mean time

struct Replicate(T)
{
Tuple!(T, uint) e;
@property bool empty() { return e[1] == 0 ; }
@property auto front() {return e[0]; }
void popFront() { --e[1]; }
}

Replicate!T replicate(T)(Tuple!(T, uint) e)
{
return typeof(return)(e);
}

f.multiwayMerge.group!"a == b".map!(replicate).writeln;

Does the same thing provided your predicate is "a == b".



Thanks Nicholas.
I posted the bug as you suggested. My predicate is not quite a == 
b, otherwise I would never have needed chunkBy in the first 
place. But thanks, I'm pursuing a workaround.


Matt


Re: Alias this and inheritance

2017-11-05 Thread ag0aep6g via Digitalmars-d-learn
On Sunday, 5 November 2017 at 07:07:43 UTC, Aurelien Fredouelle 
wrote:

struct S { }

class A
{
  S s;
  alias s this;
}

class B : A
{
}

void main()
{
  A asA = new B;
  B asB = cast(B)asA;
}

I would expect the last line to successfully cast the B 
instance I created back into type B, however this seems to be 
preempted by the alias this:


Error: cannot cast expression asA.s of type S to app.B

Is there a way to force this cast to operate on the object of 
type A instead of automatically using A.s?


Known issue: https://issues.dlang.org/show_bug.cgi?id=6777

You can work around by casting to Object first:

B asB = cast(B) cast(Object) asA;



Re: Debug info for druntime.

2017-11-05 Thread Joakim via Digitalmars-d-learn

On Saturday, 4 November 2017 at 21:54:14 UTC, ciechowoj wrote:
What is the fastest way to have the detailed debug info for 
druntime? I have a program that fails in Fiber constructor 
after I create and delete at least 68_209 Fibers one after 
another. For 68_208 works fine, one more and it aborts. I'm 
trying to use gdb to debug, but most likely don't have symbols 
for druntime.


The symbols for function names are there, just not the DWARF 
debug info, if you want to step through the corresponding source 
line by line.


I compiled the druntime from source, is there a way to make the 
dmd/dub use the source compiled version?


Assuming you want to use the debug version, you may be better off 
using ldc, which comes with debug versions of druntime and phobos 
and the -link-debuglib option, which will use those instead.  dmd 
and ldc also have the -defaultlib= and -debuglib= options, from 
which you can specify your own or a debug build of the standard 
library, with -debuglib= used if you compile with -g.


Alias this and inheritance

2017-11-05 Thread Aurelien Fredouelle via Digitalmars-d-learn

The following code does not compile:

struct S { }

class A
{
  S s;
  alias s this;
}

class B : A
{
}

void main()
{
  A asA = new B;
  B asB = cast(B)asA;
}

I would expect the last line to successfully cast the B instance 
I created back into type B, however this seems to be preempted by 
the alias this:


Error: cannot cast expression asA.s of type S to app.B

Is there a way to force this cast to operate on the object of 
type A instead of automatically using A.s?


Thanks,
Aurelien