【问题标题】:Performance of Lua calling C functionLua调用C函数的表现
【发布时间】:2023-03-24 20:53:01
【问题描述】:

我注意到我的 C 程序的性能因 -fPIC 标志而异。当我使用它时,我的程序比没有它时慢 30%。 我将它与调用 C 函数的 Lua 程序进行比较(所有繁重的计算都完成了)。首先,我使用 C 函数创建了一个共享对象,因此必须使用 -fPIC 标志。性能与带有 -fPIC 标志的 C 代码非常相似。 所以现在我尝试在没有 .so 的情况下做同样的事情:我从 C 调用 Lua:

int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    lua_register(L, "my_c_function", my_c_function);
    luaL_dofile(L, "my_lua_program.lua");
    lua_close(L);
    return 0;
}

但是无论我是否使用 -fPIC 标志,这里的性能都是相同的(并且与使用 .so 的方法相同)。我期待在没有 -fPIC 标志的情况下有所改进......关于如何进一步调查它的任何建议?第二种方法是否仍然创建与位置无关的代码,这就是性能相似的原因?谢谢!

更多信息,如评论所建议: 我使用 -O3 标志、gcc 4.7.2、Ubuntu 12.04.2、x86_64。是的,我对这么大的开销感到非常惊讶……我的程序正在计算 Mandelbrot 分形。所以有两个循环遍历 x 和 y,我在 C 中的函数是 isMandelbrot:它需要迭代次数并返回 bool:是否属于 Mandelbrot 集。我将共享对象与“require”一起使用。

【问题讨论】:

  • 您使用了哪些确切的编译标志?什么版本的编译器?什么平台和系统?什么处理器架构?位置无关代码的 30% 开销似乎是可疑的(通常是百分之几)。你的my_c_function 是做什么的?如果可能,显示它的源代码......你如何加载你的共享对象?
  • @Basile Starynkevitch - 谢谢。我用更多信息更新了这个问题。源代码的哪一部分有用?这是一个小程序,但我想在发布之前我需要做得更小。
  • 其实你的问题让我意识到为什么第二个版本没有显示出任何改进:我在 lua 代码中留下了'require'语句,所以仍然调用共享对象....不解释为什么 -fPIC 开销如此之大,但我想这应该在另一个问题中解决。再次感谢。
  • 如果可能,仔细检查 C 代码是如何编译的,显示确切的编译命令和实际代码。您的my_c_function 多久打一次电话?它运行多长时间?我对你 30% 的数字感到非常惊讶。
  • @Basile Starynkevitch 我发布了一个单独的问题(因为故事的 lua 部分不再相关),其中包含所有详细信息 here

标签: c performance gcc lua


【解决方案1】:

我认为您运行的代码是 x86。该平台在使用 -fPIC 时存在性能问题,其中任何导入函数的位置都需要找到本地 eip。执行此操作的代码为函数增加了一点开销。可惜lua里面有很多非常小的函数,会增加相对开销。

在 x64 上 -fPIC 没有这个开销。

【讨论】:

    【解决方案2】:

    好吧,首先,如果你用 c 程序或用 lua 调用 c 程序几乎没有区别,但是,每次创建 c 程序时,你都是在创建一个独立的程序,所有系统头文件都要弹出,然后,在它完成正在做的事情之后,它会报告价值。我的观点是,问题可能不是“调用”函数,而是多少和多快,因为在调用程序之后还有很多事情要做。

    o3 优化标志不是很健康,所以如果你这样做了一次,你可能还想尝试 -Ofast,只是不要使用 -Os 它可能只会让事情变得更糟......

    提高性能的最简单方法就是优化 c 代码,您可能想在编译期间尝试优化标志。 Here 是一大堆标志和大量关于 GCC 编译器下的标志的文档。请注意,并非所有这些都是安全的,也并非所有这些都是真正需要的,因此请分析您的代码并仅选择您需要的那些。

    第二种优化代码的方法被认为有点困难。您可能希望在启动 lua 脚本的同时启动 C 程序,然后在运行时(并行)交换信息,这样您每次调用时都不需要调用整个程序来显示它

    第三种,最难的方法,让您的 C 代码创建 n 个线程,其中 n

    如果你不介意,C/c++ 代码擅长数学,但有更好的语言可以让你获得更高的性能,比如 Fortran、APL、Matlab、Haskel、R,或者如果你足够疯狂并且你有对数学问题有很好的了解 - 使用 GPU 而不是 CPU -> 着色器语言,我也将它们用于一些奇怪的东西,甚至不接近图形,但它对我有用。

    【讨论】:

    • "用 c 程序或用 lua 调用 c 程序几乎没有区别" 不。从 Lua 调用的 C 函数可能需要与 Lua 堆栈交互。还有解释器开销。
    • "每次创建 c 程序时,您都在制作整个独立程序,所有系统头文件都会弹出,然后,在完成正在执行的操作后,它会报告返回值。"不。当你从 Lua 调用 C 函数时,你绝对不是在创建一个单独的进程。
    • 如果你已经创建了进程是的,这只是关于调用函数并等待结果,更早或晚你需要创建“进程”。函数不能凭空调用——没有系统依赖的操作堆栈——你需要程序或进程来保存关于每个东西的信息,然后你可以在这个进程上调用函数。此外,没有解释器开销之类的东西 - itnerpreter 只是调用函数并等待,我们正在讨论我们需要从这个函数中获得结果
    猜你喜欢
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    • 2014-09-01
    • 2014-09-11
    • 2015-07-14
    • 2013-02-19
    • 2015-12-30
    相关资源
    最近更新 更多