使用带有自定义对齐分配器实现的最新g++,使用SSE和-O3选项编译时出现非法指令(核心转储)



使用g++(GCC)4.8.3 20140911(Red Hat 4.8.3-7)使用编译命令"g++-g-fno省略帧指针-msse2-mssse3-O3 Memory.cpp"编译以下代码时,可执行文件在执行时引发"非法指令(核心转储)"。

它使用旧版g++使用完全相同的编译器标志进行编译和运行,没有问题。当编译器标志"-mssse3-O3"被删除或替换为较低的优化级别(如"-O2")时,它也可以编译和运行而不会出现问题。

如果同时使用旧的和新的g++编译器,具有编译器标志"-msse2-mssse3-O3",并具有可移植的对齐内存分配器是一项要求,那么存在哪些选项?下面的代码中是否有一个简单的错误可以很容易地修复?最后,为什么会出现这种错误?

使用gdb时,触发此错误的行是:"memory[i]=(unsigned char)i;"。

提前非常感谢。

#include <iostream>
using std::cerr;
using std::cout;
using std::endl;
using std::flush;
#include <stdlib.h>
void *aligned_alloc(int alignment, int size){
  const int pointer_size = sizeof(unsigned char *);
  const int requested_size = size + alignment - 1 + pointer_size;
  unsigned char *base = (unsigned char *)malloc(requested_size);
  if (base == NULL)  return NULL;
  unsigned char *start = base + pointer_size;
  const int trim_offset = (int)(((unsigned long long)(start+alignment-1)) & (alignment-1));
  unsigned char *aligned = start + alignment - 1 - trim_offset;
  *(unsigned char **)(aligned-pointer_size) = base;
  return aligned;
}
void aligned_free(void **aligned){
  if (*aligned == NULL)  return;
  unsigned char *base = *(unsigned char **)((unsigned char *)(*aligned) - sizeof(unsigned char *));
  free(base);
  *aligned = NULL;
}
int main(){
  unsigned char *memory = (unsigned char *)aligned_alloc(16, 120);
  if (memory == NULL){
    cout<<"ERROR: Unable to allocate memory."<<endl;
    exit(1);
  }
  for (int i=0; i<120; i++){
    memory[i] = (unsigned char)i;
  }
  aligned_free((void **)&memory);
  return 0;
}

这是由于CPU不支持SSSE3(补充数据流单指令多数据扩展指令集3)指令子集(特别是某种风格的3GHZ P4),试图运行为支持该指令子集的CPU编译的代码;简单地从GCC命令行中删除-mssse3标志就足以使有问题的指令消失。

最新更新