linux 运行obj,将C++目标文件从linux .o转换为Windows .obj

这篇博客探讨了如何将使用GCC编译的C++代码与Microsoft Visual Studio(MSVC)兼容。关键点包括设置-mabi=ms以匹配函数调用约定,使用objconv工具将目标文件从ELF格式转换为COFF/PE格式,以及处理C++函数名称修饰。作者分享了一个使用AVX指令优化的示例代码,并展示了如何在MSVC中成功链接和运行。
摘要由CSDN通过智能技术生成

Z boson..

13

有一种方法可以做到这一点,并不是那么困难.

您需要了解的主要内容是函数调用约定,对象格式和函数名称修改.

函数调用约定.

在32位模式下,Windows和Unix(即Linux,BSD,Mac OS X,...)使用相同的函数调用约定.

在64位模式下,Windows和Unix使用不同的函数调用约定.为了使用GCC编译的目标文件在64位模式下与MSVC一起使用,必须使用Windows函数调用约定.要使用gcc执行此操作,您可以使用mabi=ms例如:

g++ -c -mabi=ms -mavx -fopenmp -O3 foo.cpp

目标文件格式

Linux的目标文件格式是ELF,而Windows的目标文件格式是COFF/PE.为了在MSVC中使用用GCC编译的对象,需要将其从ELF转换为COFF.为此,您需要一个目标文件转换器.我使用Agner Fog的objconv.例如,要从ELF64转换为64位COFF64(PE32 +),请执行以下操作:

objconv -fcoff64 foo.o foo.obj

功能名称管理

由于函数重载,C++破坏了函数名称.GCC和MSVC的做法不同.为了解决这个问题,你可以继续使用函数名称external "C".

有关调用约定,对象格式和函数名称修改的更多详细信息,请参阅Agner Fog的手动调用约定.

下面是我用GCC编译的模块,然后在MSVC中使用(因为GCC更好地优化了它).我编译它-mabi=ms,将其转换为COFF64,objconv然后将其链接到运行完美的Visual Studio.

#include

extern "C" void inner(const int n, const float *a, const float *b, float *c, const int stridea, const int strideb, const int stridec) {

const int vec_size = 8;

__m256 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;

tmp0 = _mm256_loadu_ps(&c[0*vec_size]);

tmp1 = _mm256_loadu_ps(&c[1*vec_size]);

tmp2 = _mm256_loadu_ps(&c[2*vec_size]);

tmp3 = _mm256_loadu_ps(&c[3*vec_size]);

tmp4 = _mm256_loadu_ps(&c[4*vec_size]);

tmp5 = _mm256_loadu_ps(&c[5*vec_size]);

tmp6 = _mm256_loadu_ps(&c[6*vec_size]);

tmp7 = _mm256_loadu_ps(&c[7*vec_size]);

for(int i=0; i

__m256 areg0 = _mm256_set1_ps(a[i]);

__m256 breg0 = _mm256_loadu_ps(&b[vec_size*(8*i + 0)]);

tmp0 = _mm256_add_ps(_mm256_mul_ps(areg0,breg0), tmp0);

__m256 breg1 = _mm256_loadu_ps(&b[vec_size*(8*i + 1)]);

tmp1 = _mm256_add_ps(_mm256_mul_ps(areg0,breg1), tmp1);

__m256 breg2 = _mm256_loadu_ps(&b[vec_size*(8*i + 2)]);

tmp2 = _mm256_add_ps(_mm256_mul_ps(areg0,breg2), tmp2);

__m256 breg3 = _mm256_loadu_ps(&b[vec_size*(8*i + 3)]);

tmp3 = _mm256_add_ps(_mm256_mul_ps(areg0,breg3), tmp3);

__m256 breg4 = _mm256_loadu_ps(&b[vec_size*(8*i + 4)]);

tmp4 = _mm256_add_ps(_mm256_mul_ps(areg0,breg4), tmp4);

__m256 breg5 = _mm256_loadu_ps(&b[vec_size*(8*i + 5)]);

tmp5 = _mm256_add_ps(_mm256_mul_ps(areg0,breg5), tmp5);

__m256 breg6 = _mm256_loadu_ps(&b[vec_size*(8*i + 6)]);

tmp6 = _mm256_add_ps(_mm256_mul_ps(areg0,breg6), tmp6);

__m256 breg7 = _mm256_loadu_ps(&b[vec_size*(8*i + 7)]);

tmp7 = _mm256_add_ps(_mm256_mul_ps(areg0,breg7), tmp7);

}

_mm256_storeu_ps(&c[0*vec_size], tmp0);

_mm256_storeu_ps(&c[1*vec_size], tmp1);

_mm256_storeu_ps(&c[2*vec_size], tmp2);

_mm256_storeu_ps(&c[3*vec_size], tmp3);

_mm256_storeu_ps(&c[4*vec_size], tmp4);

_mm256_storeu_ps(&c[5*vec_size], tmp5);

_mm256_storeu_ps(&c[6*vec_size], tmp6);

_mm256_storeu_ps(&c[7*vec_size], tmp7);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值