forked from apache/spark
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[POAE7-497] PMem extension implementation for UnsafeExternalSorter (a…
…pache#39) * [POAE7-497] add memory manager for PMem * [POAE7-497] memory spill to PMem for UnsafeExternalSorter
- Loading branch information
Showing
19 changed files
with
1,224 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
common/unsafe/src/main/java/org/apache/spark/unsafe/memory/ExtendedMemoryAllocator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
|
||
package org.apache.spark.unsafe.memory; | ||
import com.intel.oap.common.unsafe.PersistentMemoryPlatform; | ||
|
||
public class ExtendedMemoryAllocator implements MemoryAllocator{ | ||
|
||
@Override | ||
public MemoryBlock allocate(long size) throws OutOfMemoryError { | ||
long address = PersistentMemoryPlatform.allocateVolatileMemory(size); | ||
MemoryBlock memoryBlock = new MemoryBlock(null, address, size); | ||
|
||
return memoryBlock; | ||
} | ||
|
||
@Override | ||
public void free(MemoryBlock memoryBlock) { | ||
assert (memoryBlock.getBaseObject() == null) : | ||
"baseObject not null; are you trying to use the AEP-heap allocator to free on-heap memory?"; | ||
PersistentMemoryPlatform.freeMemory(memoryBlock.getBaseOffset()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
core/src/main/java/org/apache/spark/util/collection/unsafe/sort/PMemReader.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package org.apache.spark.util.collection.unsafe.sort; | ||
|
||
import org.apache.spark.unsafe.Platform; | ||
import org.apache.spark.unsafe.memory.MemoryBlock; | ||
|
||
import java.io.Closeable; | ||
import java.util.LinkedList; | ||
|
||
public final class PMemReader extends UnsafeSorterIterator implements Closeable { | ||
private int recordLength; | ||
private long keyPrefix; | ||
private int numRecordsRemaining; | ||
private int numRecords; | ||
private LinkedList<MemoryBlock> pMemPages; | ||
private MemoryBlock pMemPage = null; | ||
private int readingPageIndex = 0; | ||
private int readedRecordsInCurrentPage = 0; | ||
private int numRecordsInpage = 0; | ||
private long offset = 0; | ||
private byte[] arr = new byte[1024 * 1024]; | ||
private Object baseObject = arr; | ||
public PMemReader(LinkedList<MemoryBlock> pMemPages, int numRecords) { | ||
this.pMemPages = pMemPages; | ||
this.numRecordsRemaining = this.numRecords = numRecords; | ||
} | ||
@Override | ||
public void loadNext() { | ||
assert (readingPageIndex <= pMemPages.size()) | ||
: "Illegal state: Pages finished read but hasNext() is true."; | ||
if(pMemPage == null || readedRecordsInCurrentPage == numRecordsInpage) { | ||
// read records from each page | ||
pMemPage = pMemPages.get(readingPageIndex++); | ||
readedRecordsInCurrentPage = 0; | ||
numRecordsInpage = Platform.getInt(null, pMemPage.getBaseOffset()); | ||
offset = pMemPage.getBaseOffset() + 4; | ||
} | ||
// record: BaseOffSet, record length, KeyPrefix, record value | ||
keyPrefix = Platform.getLong(null, offset); | ||
offset += 8; | ||
recordLength = Platform.getInt(null, offset); | ||
offset += 4; | ||
if (recordLength > arr.length) { | ||
arr = new byte[recordLength]; | ||
baseObject = arr; | ||
} | ||
Platform.copyMemory(null, offset , baseObject, Platform.BYTE_ARRAY_OFFSET, recordLength); | ||
offset += recordLength; | ||
readedRecordsInCurrentPage ++; | ||
numRecordsRemaining --; | ||
|
||
|
||
} | ||
@Override | ||
public int getNumRecords() { | ||
return numRecords; | ||
} | ||
|
||
@Override | ||
public boolean hasNext() { | ||
return (numRecordsRemaining > 0); | ||
} | ||
|
||
@Override | ||
public Object getBaseObject() { | ||
return baseObject; | ||
} | ||
|
||
@Override | ||
public long getBaseOffset() { | ||
return Platform.BYTE_ARRAY_OFFSET; | ||
} | ||
|
||
@Override | ||
public int getRecordLength() { | ||
return recordLength; | ||
} | ||
|
||
@Override | ||
public long getKeyPrefix() { | ||
return keyPrefix; | ||
} | ||
|
||
@Override | ||
public void close() { | ||
// do nothing here | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
.../java/org/apache/spark/util/collection/unsafe/sort/PMemReaderForUnsafeExternalSorter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package org.apache.spark.util.collection.unsafe.sort; | ||
|
||
import org.apache.spark.unsafe.Platform; | ||
import org.apache.spark.unsafe.UnsafeAlignedOffset; | ||
import org.apache.spark.unsafe.array.LongArray; | ||
|
||
import java.io.Closeable; | ||
|
||
public final class PMemReaderForUnsafeExternalSorter extends UnsafeSorterIterator implements Closeable { | ||
private int recordLength; | ||
private long keyPrefix; | ||
private int numRecordsRemaining; | ||
private int numRecords; | ||
private LongArray sortedArray; | ||
private int position = 0; | ||
private byte[] arr = new byte[1024 * 1024]; | ||
private Object baseObject = arr; | ||
public PMemReaderForUnsafeExternalSorter(LongArray sortedArray, int numRecords) { | ||
this.sortedArray = sortedArray; | ||
this.numRecordsRemaining = this.numRecords = numRecords; | ||
} | ||
@Override | ||
public void loadNext() { | ||
assert(position < numRecords * 2) | ||
: "Illegal state: Pages finished read but hasNext() is true."; | ||
final long address = sortedArray.get(position); | ||
keyPrefix = sortedArray.get(position + 1); | ||
int uaoSize = UnsafeAlignedOffset.getUaoSize(); | ||
recordLength = UnsafeAlignedOffset.getSize(null, address); | ||
if (recordLength > arr.length) { | ||
arr = new byte[recordLength]; | ||
baseObject = arr; | ||
} | ||
// System.out.println(numRecordsRemaining); | ||
Platform.copyMemory(null, address + uaoSize , baseObject, Platform.BYTE_ARRAY_OFFSET, recordLength); | ||
numRecordsRemaining --; | ||
position += 2; | ||
} | ||
@Override | ||
public int getNumRecords() { | ||
return numRecords; | ||
} | ||
|
||
@Override | ||
public boolean hasNext() { | ||
return (numRecordsRemaining > 0); | ||
} | ||
|
||
@Override | ||
public Object getBaseObject() { | ||
return baseObject; | ||
} | ||
|
||
@Override | ||
public long getBaseOffset() { | ||
return Platform.BYTE_ARRAY_OFFSET; | ||
} | ||
|
||
@Override | ||
public int getRecordLength() { | ||
return recordLength; | ||
} | ||
|
||
@Override | ||
public long getKeyPrefix() { | ||
return keyPrefix; | ||
} | ||
|
||
@Override | ||
public void close() { | ||
// do nothing here | ||
} | ||
} |
Oops, something went wrong.