Revert "Merge branch 'benaadams/copyfrom-perf' into dev"

This reverts commit ce61282320, reversing
changes made to 7ef70bc145.
This commit is contained in:
Stephen Halter 2016-01-14 11:47:23 -08:00
parent ce61282320
commit e5ad019575
8 changed files with 72 additions and 143 deletions

View File

@ -144,7 +144,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return handle.Libuv.buf_init( return handle.Libuv.buf_init(
result.Pin() + result.End, result.Pin() + result.End,
result.BlockEndOffset - result.End); result.Data.Offset + result.Data.Count - result.End);
} }
private static void ReadCallback(UvStreamHandle handle, int status, object state) private static void ReadCallback(UvStreamHandle handle, int status, object state)

View File

@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
{ {
const int minimumSize = 2048; const int minimumSize = 2048;
if (_tail != null && minimumSize <= _tail.BlockEndOffset - _tail.End) if (_tail != null && minimumSize <= _tail.Data.Offset + _tail.Data.Count - _tail.End)
{ {
_pinned = _tail; _pinned = _tail;
} }

View File

@ -400,7 +400,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
return; return;
} }
bytes = start.Block.BlockEndOffset - start.Index; bytes = start.Block.Data.Offset + start.Block.Data.Count - start.Index;
buffers = 1; buffers = 1;
for (var block = start.Block.Next; block != end.Block; block = block.Next) for (var block = start.Block.Next; block != end.Block; block = block.Next)

View File

@ -52,11 +52,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
/// </summary> /// </summary>
public byte[] Array => Data.Array; public byte[] Array => Data.Array;
/// <summary>
/// Fixed end offset of the block
/// </summary>
public int BlockEndOffset { get; private set; }
/// <summary> /// <summary>
/// The Start represents the offset into Array where the range of "active" bytes begins. At the point when the block is leased /// The Start represents the offset into Array where the range of "active" bytes begins. At the point when the block is leased
/// the Start is guaranteed to be equal to Array.Offset. The value of Start may be assigned anywhere between Data.Offset and /// the Start is guaranteed to be equal to Array.Offset. The value of Start may be assigned anywhere between Data.Offset and
@ -149,7 +144,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
Slab = slab, Slab = slab,
Start = data.Offset, Start = data.Offset,
End = data.Offset, End = data.Offset,
BlockEndOffset = data.Offset + data.Count
}; };
} }

View File

@ -722,52 +722,46 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
CopyFrom(buffer.Array, buffer.Offset, buffer.Count); CopyFrom(buffer.Array, buffer.Offset, buffer.Count);
} }
public unsafe void CopyFrom(byte[] data, int offset, int count) public void CopyFrom(byte[] data, int offset, int count)
{ {
Debug.Assert(_block != null); Debug.Assert(_block != null);
Debug.Assert(_block.Next == null); Debug.Assert(_block.Next == null);
Debug.Assert(_block.End == _index); Debug.Assert(_block.End == _index);
var pool = _block.Pool;
var block = _block; var block = _block;
var blockIndex = _index; var blockIndex = _index;
var bytesLeftInBlock = block.BlockEndOffset - blockIndex;
if (bytesLeftInBlock >= count) var bufferIndex = offset;
{ var remaining = count;
_index = blockIndex + count; var bytesLeftInBlock = block.Data.Offset + block.Data.Count - blockIndex;
Buffer.BlockCopy(data, offset, block.Array, blockIndex, count);
block.End = _index;
return;
}
do while (remaining > 0)
{ {
if (bytesLeftInBlock == 0) if (bytesLeftInBlock == 0)
{ {
var nextBlock = block.Pool.Lease(); var nextBlock = pool.Lease();
blockIndex = nextBlock.Data.Offset; block.End = blockIndex;
bytesLeftInBlock = nextBlock.Data.Count;
block.Next = nextBlock; block.Next = nextBlock;
block = nextBlock; block = nextBlock;
blockIndex = block.Data.Offset;
bytesLeftInBlock = block.Data.Count;
} }
if (count > bytesLeftInBlock) var bytesToCopy = remaining < bytesLeftInBlock ? remaining : bytesLeftInBlock;
{
count -= bytesLeftInBlock; Buffer.BlockCopy(data, bufferIndex, block.Array, blockIndex, bytesToCopy);
Buffer.BlockCopy(data, offset, block.Array, blockIndex, bytesLeftInBlock);
offset += bytesLeftInBlock; blockIndex += bytesToCopy;
block.End = blockIndex + bytesLeftInBlock; bufferIndex += bytesToCopy;
bytesLeftInBlock = 0; remaining -= bytesToCopy;
} bytesLeftInBlock -= bytesToCopy;
else }
{
_index = blockIndex + count; block.End = blockIndex;
Buffer.BlockCopy(data, offset, block.Array, blockIndex, count); _block = block;
block.End = _index; _index = blockIndex;
_block = block;
return;
}
} while (true);
} }
public unsafe void CopyFromAscii(string data) public unsafe void CopyFromAscii(string data)
@ -776,123 +770,64 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure
Debug.Assert(_block.Next == null); Debug.Assert(_block.Next == null);
Debug.Assert(_block.End == _index); Debug.Assert(_block.End == _index);
var pool = _block.Pool;
var block = _block; var block = _block;
var blockIndex = _index; var blockIndex = _index;
var count = data.Length; var length = data.Length;
var blockRemaining = block.BlockEndOffset - blockIndex; var bytesLeftInBlock = block.Data.Offset + block.Data.Count - blockIndex;
var bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3;
fixed (char* pInput = data) fixed (char* pData = data)
{ {
if (blockRemaining >= count) var input = pData;
var inputEnd = pData + length;
var inputEndMinusSpan = inputEnd - 3;
while (input < inputEnd)
{ {
_index = blockIndex + count; if (bytesLeftInBlock == 0)
fixed (byte* pOutput = &block.Data.Array[blockIndex])
{ {
CopyFromAscii(pInput, pOutput, count); var nextBlock = pool.Lease();
} block.End = blockIndex;
block.End = _index;
return;
}
var input = pInput;
do
{
if (blockRemaining == 0)
{
var nextBlock = block.Pool.Lease();
blockIndex = nextBlock.Data.Offset;
blockRemaining = nextBlock.Data.Count;
block.Next = nextBlock; block.Next = nextBlock;
block = nextBlock; block = nextBlock;
blockIndex = block.Data.Offset;
bytesLeftInBlock = block.Data.Count;
bytesLeftInBlockMinusSpan = bytesLeftInBlock - 3;
} }
if (count > blockRemaining) fixed (byte* pOutput = &block.Data.Array[block.End])
{ {
count -= blockRemaining; //this line is needed to allow output be an register var
var output = pOutput;
fixed (byte* pOutput = &block.Data.Array[blockIndex]) var copied = 0;
for (; input < inputEndMinusSpan && copied < bytesLeftInBlockMinusSpan; copied += 4)
{ {
CopyFromAscii(input, pOutput, blockRemaining); *(output) = (byte)*(input);
*(output + 1) = (byte)*(input + 1);
*(output + 2) = (byte)*(input + 2);
*(output + 3) = (byte)*(input + 3);
output += 4;
input += 4;
}
for (; input < inputEnd && copied < bytesLeftInBlock; copied++)
{
*(output++) = (byte)*(input++);
} }
block.End = blockIndex + blockRemaining; blockIndex += copied;
input += blockRemaining; bytesLeftInBlockMinusSpan -= copied;
blockRemaining = 0; bytesLeftInBlock -= copied;
} }
else }
{ }
_index = blockIndex + count;
fixed (byte* pOutput = &block.Data.Array[blockIndex]) block.End = blockIndex;
{ _block = block;
CopyFromAscii(input, pOutput, count); _index = blockIndex;
}
block.End = _index;
_block = block;
return;
}
} while (true);
}
}
private unsafe static void CopyFromAscii(char* pInput, byte* pOutput, int count)
{
var i = 0;
//these line is needed to allow input/output be an register var
var input = pInput;
var output = pOutput;
while (i < count - 11)
{
i += 12;
*(output) = (byte)*(input);
*(output + 1) = (byte)*(input + 1);
*(output + 2) = (byte)*(input + 2);
*(output + 3) = (byte)*(input + 3);
*(output + 4) = (byte)*(input + 4);
*(output + 5) = (byte)*(input + 5);
*(output + 6) = (byte)*(input + 6);
*(output + 7) = (byte)*(input + 7);
*(output + 8) = (byte)*(input + 8);
*(output + 9) = (byte)*(input + 9);
*(output + 10) = (byte)*(input + 10);
*(output + 11) = (byte)*(input + 11);
output += 12;
input += 12;
}
if (i < count - 5)
{
i += 6;
*(output) = (byte)*(input);
*(output + 1) = (byte)*(input + 1);
*(output + 2) = (byte)*(input + 2);
*(output + 3) = (byte)*(input + 3);
*(output + 4) = (byte)*(input + 4);
*(output + 5) = (byte)*(input + 5);
output += 6;
input += 6;
}
if (i < count - 3)
{
i += 4;
*(output) = (byte)*(input);
*(output + 1) = (byte)*(input + 1);
*(output + 2) = (byte)*(input + 2);
*(output + 3) = (byte)*(input + 3);
output += 4;
input += 4;
}
while (i < count)
{
i++;
*output = (byte)*input;
output++;
input++;
}
} }
} }
} }

View File

@ -66,7 +66,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Networking
for (var index = 0; index < nBuffers; index++) for (var index = 0; index < nBuffers; index++)
{ {
var blockStart = block == start.Block ? start.Index : block.Data.Offset; var blockStart = block == start.Block ? start.Index : block.Data.Offset;
var blockEnd = block == end.Block ? end.Index : block.BlockEndOffset; var blockEnd = block == end.Block ? end.Index : block.Data.Offset + block.Data.Count;
// create and pin each segment being written // create and pin each segment being written
pBuffers[index] = Libuv.buf_init( pBuffers[index] = Libuv.buf_init(

View File

@ -248,7 +248,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
Assert.Null(block1.Next); Assert.Null(block1.Next);
end.CopyFrom(buffer, 0, buffer.Length); end.CopyFrom(new ArraySegment<byte>(buffer));
Assert.NotNull(block1.Next); Assert.NotNull(block1.Next);

View File

@ -308,11 +308,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
// block 1 // block 1
var start = socketOutput.ProducingStart(); var start = socketOutput.ProducingStart();
start.Block.End = start.Block.BlockEndOffset; start.Block.End = start.Block.Data.Offset + start.Block.Data.Count;
// block 2 // block 2
var block2 = memory.Lease(); var block2 = memory.Lease();
block2.End = block2.BlockEndOffset; block2.End = block2.Data.Offset + block2.Data.Count;
start.Block.Next = block2; start.Block.Next = block2;
var end = new MemoryPoolIterator2(block2, block2.End); var end = new MemoryPoolIterator2(block2, block2.End);