如何在 C 程序运行时正确调用可执行文件?
How to properly call an executable in C program runtime?
我有一个 C 应用程序,其工作之一是调用可执行文件。该文件在编译期间在中间代码级别插入了性能测量例程。它可以测量时间或 L1/L2/L3 缓存未命中。换句话说,我已经修改了 LLVM 编译器以插入对该函数的调用并将结果打印到任何已编译程序的 stdout
。
现在,就像我在开头提到的那样,我想从一个单独的 C 应用程序中执行程序(并将此结果返回给 stdout
)并保存该结果。我现在的做法是:
void executeProgram(const char* filename, char* time) {
printf("Executing selected program %s...\n", filename);
char filePath[100] = "/home/michal/thesis/Drafts/output/";
strcat(filePath, filename);
FILE *fp;
fp = popen(filePath, "r");
char str[30];
if (fp == NULL) {
printf("Failed to run command\n" );
exit(1);
}
while (fgets(str, sizeof(str) - 1, fp) != NULL) {
strcat(time, str);
}
pclose(fp);
}
其中 filename
是编译后的可执行文件的名称 运行。结果保存到 time
字符串。
问题是,与通过简单地从命令行 运行 运行可执行文件 'by hand' 返回的结果相比,我得到的结果非常不同且不稳定 (./test16
).它们看起来像:
231425
229958
230450
228534
230033
230566
231059
232016
230733
236017
213179
90515
229775
213351
229316
231642
230875
所以它们大多在 230000 us 左右,偶尔会有一些下降。另一个应用程序中的相同可执行文件 运行 生成:
97097
88706
91418
97970
97972
94597
95846
95139
91070
95918
107006
89988
90882
91986
90997
88824
129136
94976
102191
94400
95215
95061
92115
96319
114091
95230
114500
95533
102294
108473
105730
请注意,调用的是 相同的 可执行文件。然而它 returns 的测量时间是不同的。正在测量的程序包括对简单嵌套循环的函数调用,访问数组元素。这是代码:
#include "test.h"
#include <stdio.h>
float data[1000][1000] = {0};
void test(void)
{
int i0, i1;
int N = 80;
float mean[1000];
for (i0 = 0; i0 < N; i0++)
{
mean[i0] = 0.0;
for (i1 = 0; i1 < N; i1++) {
mean[i0] += data[i0][i1];
}
mean[i0] /= 1000;
}
}
我怀疑在代码中调用程序的方式有问题,也许应该分叉进程或其他什么?有什么想法吗?
您没有指定时间测量子程序的确切插入位置,所以我只能提供猜测。
结果似乎暗示恰恰相反 - 运行从 shell 启动应用程序速度较慢,因此我不会担心您从 C 启动进程的方式代码。我的猜测是 - 当您 运行 来自 shell 的程序时,是终端拖慢了您的速度。当您从 C 代码 运行ning 进程时,您将输出通过管道返回到您的 'starter' 应用程序,该应用程序已经在管道上等待输入。
作为旁注,考虑从 strcat
切换到更安全的东西,例如 strncat
。
我有一个 C 应用程序,其工作之一是调用可执行文件。该文件在编译期间在中间代码级别插入了性能测量例程。它可以测量时间或 L1/L2/L3 缓存未命中。换句话说,我已经修改了 LLVM 编译器以插入对该函数的调用并将结果打印到任何已编译程序的 stdout
。
现在,就像我在开头提到的那样,我想从一个单独的 C 应用程序中执行程序(并将此结果返回给 stdout
)并保存该结果。我现在的做法是:
void executeProgram(const char* filename, char* time) {
printf("Executing selected program %s...\n", filename);
char filePath[100] = "/home/michal/thesis/Drafts/output/";
strcat(filePath, filename);
FILE *fp;
fp = popen(filePath, "r");
char str[30];
if (fp == NULL) {
printf("Failed to run command\n" );
exit(1);
}
while (fgets(str, sizeof(str) - 1, fp) != NULL) {
strcat(time, str);
}
pclose(fp);
}
其中 filename
是编译后的可执行文件的名称 运行。结果保存到 time
字符串。
问题是,与通过简单地从命令行 运行 运行可执行文件 'by hand' 返回的结果相比,我得到的结果非常不同且不稳定 (./test16
).它们看起来像:
231425
229958
230450
228534
230033
230566
231059
232016
230733
236017
213179
90515
229775
213351
229316
231642
230875
所以它们大多在 230000 us 左右,偶尔会有一些下降。另一个应用程序中的相同可执行文件 运行 生成:
97097
88706
91418
97970
97972
94597
95846
95139
91070
95918
107006
89988
90882
91986
90997
88824
129136
94976
102191
94400
95215
95061
92115
96319
114091
95230
114500
95533
102294
108473
105730
请注意,调用的是 相同的 可执行文件。然而它 returns 的测量时间是不同的。正在测量的程序包括对简单嵌套循环的函数调用,访问数组元素。这是代码:
#include "test.h"
#include <stdio.h>
float data[1000][1000] = {0};
void test(void)
{
int i0, i1;
int N = 80;
float mean[1000];
for (i0 = 0; i0 < N; i0++)
{
mean[i0] = 0.0;
for (i1 = 0; i1 < N; i1++) {
mean[i0] += data[i0][i1];
}
mean[i0] /= 1000;
}
}
我怀疑在代码中调用程序的方式有问题,也许应该分叉进程或其他什么?有什么想法吗?
您没有指定时间测量子程序的确切插入位置,所以我只能提供猜测。
结果似乎暗示恰恰相反 - 运行从 shell 启动应用程序速度较慢,因此我不会担心您从 C 启动进程的方式代码。我的猜测是 - 当您 运行 来自 shell 的程序时,是终端拖慢了您的速度。当您从 C 代码 运行ning 进程时,您将输出通过管道返回到您的 'starter' 应用程序,该应用程序已经在管道上等待输入。
作为旁注,考虑从 strcat
切换到更安全的东西,例如 strncat
。