// constructor for memory page with segmented type public H1GpuMemoryAllocInfo(H1GpuMemoryBlock newBlock) { m_MemoryBlockRef = newBlock; H1GpuMemoryPage page = m_MemoryBlockRef.MemoryPage; // this constructor should trigger by segmented type only if (page.PageType != H1GpuMemoryPageType.Segmented) { throw new InvalidOperationException("Invalid parameter for this constructor!"); } // set appropriate properties with memory chunk H1GpuMemoryChunk chunk = page.Owner; SetProperties(chunk); }
public H1GpuMemoryBlock Allocate(Int32 size) { // calculate number of blocks we need to allocate Int32 numSegments = -1; numSegments = (size + m_PageSegmentSize) / m_PageSegmentSize; // if available memory blocks are not initialized yet, update them if (m_AvailableMemoryBlocks[0] == null) { UpdateAvailableMemoryBlocks(); } // among available memory blocks, find the best fit block Int32 minEvaluatedValue = Int32.MaxValue; Int32 minEvaluatedIndex = -1; Int32 currIndex = 0; foreach (H1GpuMemoryBlock memoryBlock in m_AvailableMemoryBlocks) { Int32 evaluatedValue = memoryBlock.Counts - numSegments; if (evaluatedValue > 0 && minEvaluatedValue > evaluatedValue) { // update the values minEvaluatedIndex = currIndex; minEvaluatedValue = evaluatedValue; } currIndex++; } // there is no available memory for this page if (minEvaluatedIndex == -1) { return(null); } H1GpuMemoryBlock newBlock = m_AvailableMemoryBlocks[minEvaluatedIndex]; // update available memory blocks UpdateAvailableMemoryBlocks(); return(newBlock); }
public void Deallocate(H1GpuMemoryBlock block) { // apply alloc bits as deallocated Int32 startIndex = block.Start; Int32 counts = block.Counts; for (Int32 index = startIndex; index < counts; ++index) { // reset alloc bit as deallocated (free space) m_AllocBits.Set(index, false); } // invalidate memory block block.Invalidate(); // update available memory blocks UpdateAvailableMemoryBlocks(); }
protected H1GpuMemoryAllocInfo AllocateWithSegmented(Int32 size) { if (m_Pages.Count == 0) { CreateNewPageSegmented(); } // allocate memory H1GpuMemoryBlock newBlock = m_AvailablePage.Allocate(size); // not enough memory we need to make new page if (newBlock == null) { // create new page and allocate newly assigned available page CreateNewPageSegmented(); newBlock = m_AvailablePage.Allocate(size); } // update available memory page UpdateAvailableMemoryPageSegmented(); return(new H1GpuMemoryAllocInfo(newBlock)); }
protected void UpdateAvailableMemoryBlocks() { Boolean isContiguous = false; Int32 contiguousAllocBitsNum = 0; List <H1GpuMemoryBlock> allAvailableMemoryBlocksInPage = new List <H1GpuMemoryBlock>(); // find all available memory blocks Int32 startIndex = 0; Int32 currIndex = 0; foreach (Boolean allocBit in m_AllocBits) { if (allocBit == false && isContiguous == false) { isContiguous = true; startIndex = currIndex; contiguousAllocBitsNum = 1; } else if (allocBit == true && isContiguous == true) { // if previously contiguous segments exists if (contiguousAllocBitsNum > 0) { // add available memory block H1GpuMemoryBlock newBlock = new H1GpuMemoryBlock(this, startIndex, contiguousAllocBitsNum); allAvailableMemoryBlocksInPage.Add(newBlock); } // reset tracking temp values isContiguous = false; contiguousAllocBitsNum = 0; } else if (allocBit == false && isContiguous == true) { contiguousAllocBitsNum++; } else // allocBit == true && isContiguous == false { // do nothing } // update index currIndex++; } // sort allAvailableMemoryBlocksInPage by memory segment counts allAvailableMemoryBlocksInPage.OrderBy(x => x.Counts); // extract largest three memory blocks // zero out the m_AvailableMemoryBlocks Array.Clear(m_AvailableMemoryBlocks, 0, m_AvailableMemoryBlocks.Count()); // reuse currIndex variable currIndex = 0; foreach (H1GpuMemoryBlock block in allAvailableMemoryBlocksInPage) { if (currIndex > 3) { break; } m_AvailableMemoryBlocks[currIndex] = block; } }