简体   繁体   English

就性能而言,就共享库文件而言,“针对架构进行编译”与“在机器上进行编译”一样好吗?

[英]In terms of performance, and in respect of shared library files, is “compiled for an architecture” as good as “compiled on a machine”?

I am working on a project that is mostly Java. 我正在从事一个主要是Java的项目。 The application is extremely computationally intensive (it performs several mathematical operations such as exponentiations and multiplications on 2048-bit numbers). 该应用程序的计算量非常大(它执行一些数学运算,例如对2048位数字进行求幂和乘法)。 Performance is important, users want to get the results as quickly as possible. 性能很重要,用户希望尽快获得结果。

Initially, all of the code was Java, however the most computationally intensive parts of the application have been re-implemented in C and in C++ for performance reasons (some parts in C and some parts in C++). 最初,所有代码都是Java,但是出于性能方面的考虑,应用程序中计算量最大的部分已在C和C ++中重新实现(C中的某些部分以及C ++中的某些部分)。

The application itself detects if certain shared library files are available or not on the path, if it finds these libraries then it uses them, if it does not find them, everything is done in Java. 应用程序本身会检测路径上是否有某些共享库文件,如果找到这些库,则使用它们;如果找不到这些库,则一切都用Java完成。

The Java application uses JNI to make calls to the native code. Java应用程序使用JNI来调用本机代码。

The C and in C++ use the GMP library ( https://gmplib.org ) to perform mathematical operations. C和C ++中的C使用GMP库( https://gmplib.org )执行数学运算。

At the moment, the distribution file that is distributed to users includes a jar (containing the compiled Java code), C and C++ source code, and scripts to compile the C and C++ code, and to execute the application. 目前,分发给用户的分发文件包括jar(包含已编译的Java代码),C和C ++源代码以及用于编译C和C ++代码并执行应用程序的脚本。

The build process that users have to perform is the following: 用户必须执行的构建过程如下:

  1. Download, compile and configure GMP. 下载,编译和配置GMP。

  2. Compile the C code to a shared library file (dll on windows, .so on linux), for example, on Linux, users execute: 将C代码编译为共享库文件(在Windows上为dll,在Linux上为.so),例如,在Linux上,用户执行:

    gcc -fPIC -shared -O2 -o ../lib/libconnectorgmp.so -I$$JAVA_HOME/include/ -I$$JAVA_HOME/include/linux -I include NativeAdapter.c ../include/libgmp.a gcc -fPIC -shared -O2 -o ../lib/libconnectorgmp.so -I $$ JAVA_HOME / include / -I $$ JAVA_HOME / include / linux-我包括NativeAdapter.c ../include/libgmp.a

  3. Compile the C++ code to a shared library file, for example, on Linux, user execute: 将C ++代码编译为共享库文件,例如,在Linux上,用户执行:

    g++ -fPIC -shared -O2 -o ../lib/libNativeLimMultiExpo.so -I$$JAVA_HOME/include/ -I$$JAVA_HOME/include/linux -I include NativeLimMultiExpo.cpp MultiExponentiation.cpp MultiExponentiation.h ../include/libgmp.a g ++ -fPIC -shared -O2 -o ../lib/libNativeLimMultiExpo.so -I $$ JAVA_HOME / include / -I $$ JAVA_HOME / include / linux -I include NativeLimMultiExpo.cpp MultiExponentiation.cpp MultiExponentiation.h ../include /libgmp.a

Notes: 笔记:

  1. ../include/libgmp.aa is a file that was generated in step 1. ../include/libgmp.aa是在步骤1中生成的文件。

  2. the .c, .cpp and .h files are application code. .c,.cpp和.h文件是应用程序代码。

Once the user has executed these steps, they will have two shared library files, and they then include these in the path when calling the Java application. 一旦用户执行了这些步骤,它们将具有两个共享库文件,然后在调用Java应用程序时将它们包括在路径中。

This build process works fine. 此构建过程运行良好。 When the shared libraries are generated and used the performance is normally around 5 times faster then purely Java. 生成并使用共享库后,性能通常比纯Java快5倍左右。

The question is, would the same performance be achieved if compiled versions of the libraries files were distributed to users. 问题是,如果将库文件的编译版本分发给用户,是否可以实现相同的性能。 In that case, 32-bit and 64-bit libraries for Windows and Linux would be distributed. 在这种情况下,将分发适用于Windows和Linux的32位和64位库。

I guess that a compiled GMP object file would also be included in those libraries, so that users would not have to do step 1 of the current build process either. 我猜想这些库中也将包含一个已编译的GMP目标文件,因此用户也不必执行当前构建过程的第1步。

One big advantage would be the users would have to perform less steps, but I don't know if the performance would be less. 一个很大的优势是用户将不必执行更少的步骤,但是我不知道性能是否会更低。

I guess the question could be stated as: "Is compiled for an architecture" as good as "compiled on a machine", in terms of performance? 我想这个问题可以这样说:就性能而言,“是否针对架构编译”和“针对机器编译”一样好?

Compiling code with very specific compiler flags for a specific machine's hardware should in principle get the best performance. 原则上,使用特定机器硬件的非常特定的编译器标志来编译代码应该获得最佳性能。

However in practice I think that as you are using GMP under the hood, the bulk of optimization is already done simply by using GMP. 但是在实践中,我认为当您在内部使用GMP时,大部分优化已经简单地通过使用GMP来完成。 The speed-up of using any GMP instead of Java's BigInteger is much greater than anything else, which will probably be close to immeasurable at best. 使用任何 GMP代替Java的BigInteger的速度要比其他任何方式都要快得多,这充其量可能几乎是无法估量的。

Modern C/C++ compilers optimize really well. 现代C / C ++编译器的优化非常好。 Leave them to it. 留给他们吧。

Java and JNI are probably imposing an overhead that I'd be sorely tempted to get rid of if performance is so critical. Java和JNI可能会产生开销,如果性能如此关键,我将非常想摆脱它。 JNI and Java come with overheads optimized C/C++ will not. JNI和Java附带开销,而优化的C / C ++则不会。 In other words, skip Java entirely and go with pure C/C++. 换句话说,完全跳过Java并使用纯C / C ++。

I am dubious of distributing a build system and sources as your describe. 我怀疑会按照您的描述分发构建系统和资源。 This has many disadvantages, not least of which is that it forces user's to become developers. 这有许多缺点,尤其是它迫使用户成为开发人员。 If, for example, GMP issue a new version with improvements ( which is quite possible ) your users now have to rebuild the application from new sources or simply put up with what they have. 例如,如果GMP发行了具有改进的新版本(这很有可能),那么您的用户现在必须从新来源重建应用程序,或者干脆忍受他们拥有的内容。 The same does if security patches fixes are issued. 如果发布了安全补丁程序修复程序,也是如此。

I think it is generally better to install generic libraries like GMP in a way that permits easy upgrades and replacement in a manner the library distributors recommend. 我认为通常最好以库发行人推荐的方式安装易于升级和替换的GMP之类的通用库。

So overall to gain performance : 因此总体上可以获得性能:

  • ditch Java entirely, use 100% C/C++ 完全放弃Java,使用100%C / C ++

  • leave the compiler to work out how best to optimize ( just -O3 ). 让编译器来研究如何进行最佳优化(仅-O3)。

And don't distribute GMP yourself. 并且不要自己分发GMP。 It's making a problem you don't need. 这是您不需要的问题。

A minor point : 次要点:

some parts in C and some parts in C++ C的某些部分和C ++的某些部分

That's not something I generally recommend. 我一般不建议这样做。 Pick one or the other. 选择一个或另一个。 You are effectively mixing three different languages ( with Java ) and it simply creates potential issues. 您正在有效地混合三种不同的语言(使用Java),并且这只会造成潜在的问题。 If you're using C++, use it everywhere would be my suggestion. 如果您使用的是C ++,那么我建议您随处使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM