我正在改进一个程序以在 Linux 中使用静态分配的大页面,而不是标准的 4Kb 页面。我已经建立了一个支持静态大页面的系统,并在大页面池(/prov/sys/vm/nr_hugepages)中分配了大量的大页面。我现在希望通过程序找到大型 malloc() 发生的位置,以便我可以删除 malloc() 并将其替换为设置了 SHM_HUGETLB 标志的 shmget/shmat。
请记住,这是高度并发的程序。
我使用共享内存的目标不是以共享方式实际使用内存。我想保留 malloc() 例程的所有功能,同时只使用静态分配的大页面支持。
下面是我要完成的示例代码段。在程序达到这一点之前,它已经分叉了许多进程。每个进程将同时执行这段代码。最初,该段仅包含以下代码:
if( !( PANEL->WORK = (void *)malloc( (size_t)(lwork) *
sizeof( double ) ) ) )
{
HPL_pabort( __LINE__, "HPL_pdpanel_init",
"Memory allocation failed" );
}
哪个工作正常。
现在我已将其修改为:
注意!!:我使用随机数作为密钥,因此每个进程都有一个随机密钥来标识它的独立内存分配。
int shmid1;
size_t dsize = (size_t)(lwork) * sizeof( double );
/*2097152 is 2MB or the huge page size, if memory request is less,
resort to standard malloc */
if( dsize < 2097152) {
if( !( PANEL->WORK = (void *)malloc(dsize) ) )
{
HPL_pabort( __LINE__, "HPL_pdpanel_init",
"Memory allocation failed" );
}
}
else {
/* Get random number to use as a key */
int randomData = open("/dev/random",O_RDONLY);
int random;
read(randomData, &random, sizeof(random));
close(randomData);
/* Get shared memory segment */
shmid1 = shmget(random, dsize, SHM_HUGETLB
| IPC_CREAT | SHM_R
| SHM_W);
if ( shmid1 < 0 ) {
perror("shmget");
exit(1);
}
printf("HugeTLB shmid: 0x%x\n", shmid1);
PANEL->WORK = (void *)shmat(shmid1, 0, 0);
}
每当我尝试从 PANEL->WORK 读取时,使用这个新实现时,我都会遇到分段错误。在我真正开始深入研究为什么这是段错误之前,我不禁想知道我是否正确地处理了这个问题。这是解决这个问题的最佳方法吗?有人认为这种方法有错误吗?