Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 针对不同的目标体系结构进行编译和优化_C++_Optimization_Gcc_Compilation - Fatal编程技术网

C++ 针对不同的目标体系结构进行编译和优化

C++ 针对不同的目标体系结构进行编译和优化,c++,optimization,gcc,compilation,C++,Optimization,Gcc,Compilation,摘要:我想利用编译器优化和处理器指令集,但仍然有一个可移植的应用程序(在不同的处理器上运行)。通常我确实可以编译5次,让用户选择正确的一个运行 我的问题是:如何实现自动化,以便在运行时检测处理器并执行正确的可执行文件,而无需用户选择它 我有一个有很多低级数学计算的应用程序。这些计算通常会运行很长时间 我希望尽可能多地利用优化,最好也利用(不总是受支持的)指令集。另一方面,我希望我的应用程序是可移植的,易于使用(所以我不希望编译5个不同的版本,让用户选择) 是否有可能编译我的代码的5个不同版本,

摘要:我想利用编译器优化和处理器指令集,但仍然有一个可移植的应用程序(在不同的处理器上运行)。通常我确实可以编译5次,让用户选择正确的一个运行

我的问题是:如何实现自动化,以便在运行时检测处理器并执行正确的可执行文件,而无需用户选择它


我有一个有很多低级数学计算的应用程序。这些计算通常会运行很长时间

我希望尽可能多地利用优化,最好也利用(不总是受支持的)指令集。另一方面,我希望我的应用程序是可移植的,易于使用(所以我不希望编译5个不同的版本,让用户选择)

是否有可能编译我的代码的5个不同版本,并在执行时动态运行最优化的版本?对于5个不同的版本,我指的是不同的指令集和处理器的不同优化

我不关心应用程序的大小

目前,我正在Linux上使用gcc(我的代码是C++),但我也对英特尔编译器和编译到Windows的编译器感兴趣

可执行文件不必能够在不同的操作系统上运行,但理想情况下,也可以自动选择32位和64位

编辑:请给出清晰的指示如何做,最好是小代码示例或解释链接。从我的观点来看,我需要一个超级通用的解决方案,它适用于我以后的任何一个随机C++项目。 编辑我把赏金分配给了ShuggyCoUk,他有大量的指针要寻找。我本想把它分成多个答案,但这是不可能的。我还没有实现这个,所以这个问题仍然“悬而未决”!请继续添加和/或改进答案,即使不再有悬赏

谢谢大家

你会用脚本吗

您可以使用脚本检测CPU,并动态加载针对体系结构优化程度最高的可执行文件。它也可以选择32/64位版本

如果您使用的是Linux,则可以使用

cat /proc/cpuinfo
您可能可以在windows上使用bash/perl/python脚本或windows脚本主机来实现这一点。您可能不想强制用户安装脚本引擎。一个能在开箱即用的操作系统IMHO上工作的最好

事实上,在windows上,您可能希望编写一个小型C#应用程序,以便更轻松地查询体系结构。C#应用程序可以生成任何最快的可执行文件


或者,您可以将不同版本的代码放入dll或共享对象中,然后根据检测到的体系结构动态加载它们。只要他们有相同的呼叫签名,它就应该工作。

是的,这是可能的。将所有不同优化的版本编译为具有公共入口点的不同动态库,并提供可加载和运行的可执行存根
根据配置文件或其他信息,在运行时通过入口点选择正确的库。

既然您提到您使用的是GCC,我就假设您的代码是C(或C++)

Neil Butterworth已经建议创建单独的动态库,但这需要一些非常重要的跨平台注意事项(在Linux、Windows、OSX等平台上手动加载动态库是不同的,而且正确地加载动态库可能需要一些时间)

一个便宜的解决方案是使用唯一的名称编写所有变体,并在运行时使用函数指针选择合适的变量

我怀疑函数指针引起的额外解引用将由您正在做的实际工作分摊(但您需要确认这一点)


此外,获得不同的编译器优化可能需要不同的.c/.cpp文件,以及对构建工具进行一些调整。但它的总体工作可能不如单独的库(它们已经以某种形式需要它了)。

看看liboil:。它可以在运行时动态选择多媒体相关计算的实现。您可能会发现,您可以使用liboil本身,而不仅仅是它的技术。

因为您没有指定是否对文件数量有限制,所以我提出了另一种解决方案:编译5个可执行文件,然后创建第六个可执行文件来启动相应的二进制文件。下面是一些针对Linux的伪代码

int main(int argc, char* argv[])
{
    char* target_path[MAXPATH];
    char* new_argv[];
    char* specific_version = determine_name_of_specific_version();
    strcpy(target_path, "/usr/lib/myapp/versions");
    strcat(target_path, specific_version);

    /* append NULL to argv */
    new_argv = malloc(sizeof(char*)*(argc+1));
    memcpy(new_argv, argv, argc*sizeof(char*));
    new_argv[argc] = 0;
    /* optionally set new_argv[0] to target_path */

    execv(target_path, new_argv);
}

另一方面,这种方法允许向用户透明地提供32位和64位二进制文件,这与已经提出的任何库方法不同。另一方面,Win32中没有execv(但cygwin中有一个很好的模拟);在Windows上,您必须创建一个新进程,而不是重新执行当前进程。

您提到了英特尔编译器。这很有趣,因为默认情况下它可以做类似的事情。然而,有一个陷阱。英特尔编译器没有插入对适当SSE功能的检查。相反,他们检查你是否有特定的英特尔芯片。违约案件仍将缓慢发生。因此,AMD CPU将无法获得合适的SSE优化版本。有一些黑客会用正确的SSE检查取代Intel检查


32/64位的差异将需要两个可执行文件。ELF和PE格式都将此信息存储在Executables头中。默认情况下启动32位版本并不太难,请检查您是否在64位系统上,然后重新启动64位版本。但在安装时创建适当的符号链接可能更容易。

若您希望它能在Windows上干净地工作,并充分利用附加1的64位平台。添加