下面是我对来自著名 LAPACK 数值库的 Fortran ZHEEVR 例程的 C 包装器:
void zheevr(char jobz, char range, char uplo, int n, doublecomplex* a, int lda, double vl, double vu, int il, int iu, double abstol, double* w, doublecomplex* z, int ldz, int* info)
{
int m;
int lwork = -1;
int liwork = -1;
int lrwork = -1;
int* isuppz = alloc_memory(sizeof(int) * 2 * n);
zheevr_(&jobz, &range, &uplo, &n, a, &lda, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, small_work_doublecomplex, &lwork, small_work_double, &lrwork, small_work_int, &liwork, &info);
lwork = (int) small_work_doublecomplex[0].real;
liwork = small_work_int[0];
lrwork = (int) small_work_double[0];
doublecomplex* work = alloc_memory(sizeof(doublecomplex) * lwork);
double* rwork = alloc_memory(sizeof(double) * lrwork);
int* iwork = alloc_memory(sizeof(int) * liwork);
zheevr_(&jobz, &range, &uplo, &n, a, &lda, &vl, &vu, &il, &iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork, rwork, &lrwork, iwork, &liwork, info);
free(iwork);
free(rwork);
free(work);
free(isuppz);
}
该函数在我的应用程序中被调用了数十万次,以对相同矩阵大小的复矩阵“a”(参数名称遵循该函数的 Fortran 约定)进行对角化。我认为工作数组的大小在大多数情况下都是相同的,因为对角化矩阵将具有相同的结构。我的问题是:
- 重复的 alloc/free(“alloc_memory”是 glibc 的 malloc 的简单包装器)调用会损害性能吗?有多严重?
- 免费的顺序重要吗?我应该先释放最后分配的数组,还是最后释放?