Ethernet Multicast Stream Sockets pipelined Stream Sockets
If somebody has access to infiniband or myrinet, it would be great to have support for this networks.
In a cluster system often a huge amount of data has to be sent to a lot of receivers. For example in OpenSG the change list has to be sent to all rendering nodes in each frame. As there is a wide variety to do this best with different networks, there is a special connection type that encapsulates multipoint and single point connections.
Communication is the most critical point in clustering. This the communication overhead has to be as small as possible. Because of this we do no special encoding to guarantee that a receiver gets the data it expects. For example if a sender sends Real32 values and a receiver reads Int32 values, this will not be detected by any mechanism of the communication framework. So if you send data over a connection, the receiver must exactly know how many data it has to read and in wich type the data is encoded. This makes debugging of communications sometimes very difficult but the advantage is that the available bandwidth is fully available for the data transfer.
There are two types of connections. A PointConnection is used to send and receive with one communication endpoint. A GroupConnection is used to send and receive from one or more communication endpoints. GroupConnections can be used to multicast data simultaniously to many destinations. It is possible to communicate between two PointConnections and between a GroupConnection and many PointConnections.
GroupConnection *group = ConnectionFactory::the().createGroup("Multicast"); PointConnection *point = ConnectionFactory::the().createPoint("Multicast"); PointConnection *group = new GroupSockConnection(); PointConnection *point = new PointSockConnection();
Connecting two PointConnections:
// Host 1 Connection::Channel c = point.connectPoint("196.168.1.22:1234"); if(c < 0) return -1; // Host 2 point.bind(":1234"); Connection::Channel c = point.acceptPoint(); if(c < 0) return -1;
Connecting tree PointConnections with one GroupConnection
// Host 1 if(point.connectGroup("196.168.1.22:1234") < 0) return -1; // Host 2 if(point.connectGroup("196.168.1.22:1234") < 0) return -1; // Host 3 if(point.connectGroup("196.168.1.22:1234") < 0) return -1; // Host 4 point.bind(":1234"); Connection::Channel c; if(point.acceptPoint() < 0) return -1 if(point.acceptPoint() < 0) return -1 if(point.acceptPoint() < 0) return -1
Connecting one GroupConnection with tree PointConnections
// Host 1 point.bind(":1234"); if(point.acceptGroup() < 0) return -1; // Host 2 point.bind(":1234"); if(point.acceptGroup() < 0) return -1; // Host 3 point.bind(":1234"); if(point.acceptGroup() < 0) return -1; // Host 4 point.bind(":1234"); Connection::Channel c; // wait a maximum of 40 seconds for each connection if(point.connectPoint("196.168.1.30:1234",40) < 0) return -1 if(point.connectPoint("196.168.1.31:1234",40) < 0) return -1 if(point.connectPoint("196.168.1.32:1234",40) < 0) return -1
All methods that establish a connection return a Channel id or -1 on error. Channel ids can be used in GroupConnections to distinguish incomming messages.
UInt32 count; Real32 values[100]; connection->putValue(count); connection->putValues(values,100); connection->flush(); .. connection->selectChannel(); connection->getValue(count); connection->getValues(values,100);
putValue, putValues, getValue and getValues are doing a network byte order encoding if both endpoints are based on different architectures. This can be switched off if a homogenious cluster is used.
connection->setNetworkOrder(false);
By default a connection tries to minimize the number of data that is copyied. To do this, for lage memory blocks only a tag is written in the output buffer. If the buffer is full or flush is called, then first the buffer is send and afterwards the large memory blocks. Thise technique provides buffering for mall data blocks and unbufferd transmission for large blocks. This is very efficient and works fine as long as the data is not modified between putValue and the actual data transmission. If this can not be guaranteed, then a copy operation can be forced. This option must be set by both communication endpoints.
connection->forceCopy();
In forceCopy mode the whole data is bufferd. In contrast an unbuffered mode can be enabled with forceDirectIO method.
connection->forceDirectIO();
It is not possible to change the transmission mode for connected Connections.
Connection::Channel channel; while(group->getSelectionCount() > 0) { channel = mConnection->selectChannel(); group->getValue(result); // Getting data group->subSelection(channel); } mConnection->resetSelection();
// Host 1 point->wait(); // Host 2 point->wait(); // Host 3 point->wait(); // Host 4 group->signal();
connectionA->setInterface("196.168.10.22"); connectionB->setInterface("134.213.21.11"); // accept from network 1 connectionA->bind(":1234"); connectionA->accept(); // accept from network 2 connectionB->bind(":1234"); connectionB->accept();
group->setDestination("237.32.12.22"); group->bind(":4432") if(group->acceptPoint() < 0) return -1;
1.5.5