docs/design/features/Linux-Hugepage-Crossgen2.md
Huge pages can provide performance benefits to reduce the cost of TLB cache misses when executing code. In general, the largest available wins may be achieved by enabling huge pages for use by the GC, which will dominate the memory use in the process, but in some circumstances, if the application is sufficiently large, there may be a benefit to using huge pages to map in code.
It is expected that consumers who have these needs have very large applications, and are able to tolerate somewhat complex solutions. CoreCLR supports loading composite R2R images using the hugetlbfs. Doing some requires several steps.
--custom-pe-section-alignment=2097152. This will align the PE sections in the R2R file on 2MB virtual address boundaries, and align the sections in the PE file itself on the same boundaries.DOTNET_NativeImageSearchPaths must be set to point at the location of the hugetlbfs in use. For instance, DOTNET_NativeImageSearchPaths might be set to /var/lib/hugetlbfs/user/USER/pagesize-2MBlink /dump /header compositeimage.dll to determine the number of pages needed for the these .data section of the PE file.)
<Count of huge pages for composite file> + <count of processes to run> * <count of huge pages needed for the .data section of the composite file>Appendix A - Source for a simple copy into hugetlbfs program.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv)
{
if (argc != 3)
{
printf("Incorrect number arguments specified. Arguments are <src> <dest>");
return 1;
}
void *addrSrc, *addrDest;
int fdSrc, fdDest, ret;
fdSrc = open(argv[1], O_RDWR);
if (fdSrc < 0)
{
printf("Open src failed\n");
return 1;
}
struct stat st;
if (fstat(fdSrc, &st) < 0)
{
printf("fdSrc fstat failed\n");
return 1;
}
addrSrc = mmap(0, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdSrc, 0);
if (addrSrc == MAP_FAILED)
{
printf("fdSrc mmap failed\n");
return 1;
}
fdDest = open(argv[2], O_CREAT | O_RDWR, 0755);
if (fdDest < 0)
{
printf("Open dest failed\n");
return 1;
}
if (ftruncate(fdDest, st.st_size) < 0)
{
printf("ftruncate failed\n");
return 1;
}
addrDest = mmap(0, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fdDest, 0);
if (addrDest == MAP_FAILED)
{
printf("fdDest mmap failed\n");
return 1;
}
memcpy(addrDest, addrSrc, st.st_size);
munmap(addrSrc, st.st_size);
munmap(addrDest, st.st_size);
close(fdSrc);
close(fdDest);
return 0;
}