2

我正在改进一个程序以在 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 读取时,使用这个新实现时,我都会遇到分段错误。在我真正开始深入研究为什么这是段错误之前,我不禁想知道我是否正确地处理了这个问题。这是解决这个问题的最佳方法吗?有人认为这种方法有错误吗?

4

0 回答 0