【问题标题】:Array Error - Access violation reading location 0xffffffff数组错误 - 访问冲突读取位置 0xffffffff
【发布时间】:2012-10-22 14:36:15
【问题描述】:

我以前使用 SIMD 运算符来提高我的代码效率,但是我现在面临一个我无法解决的新错误。对于这项任务,速度至关重要。

在导入数据之前,数组的大小是未知的,可能非常小(100 个值)或巨大(1000 万个值)。对于后一种情况,代码可以正常工作,但是当我使用少于 130036 个数组值时遇到错误。

有谁知道是什么导致了这个问题以及如何解决它?

我附上了相关的(测试过的)代码,稍后将在更复杂的函数中使用。错误发生在“arg1List[i] = ...”

#include <iostream>
#include <xmmintrin.h>
#include <emmintrin.h>

void main()
{
    int j;
    const int loop = 130036;
    const int SIMDloop = (int)(loop/4);
    __m128 *arg1List = new __m128[SIMDloop];

    printf("sizeof(arg1List)= %d, alignof(Arg1List)= %d, pointer= %p", sizeof(arg1List), __alignof(arg1List), arg1List);
    std::cout << std::endl;

    for (int i = 0; i < SIMDloop; i++)
    {
        j = 4*i;
        arg1List[i] = _mm_set_ps((j+1)/100.0f, (j+2)/100.0f, (j+3)/100.0f, (j+4)/100.0f);
    }
}

【问题讨论】:

标签: c++ sse simd


【解决方案1】:

对齐是原因。

MOVAPS--移动对齐的压缩单精度浮点值

[...] 操作数必须在 16 字节边界上对齐,否则将生成通用保护异常 (#GP)。

您可以看到问题在您对齐指针后立即消失:

__m128 *arg1List = new __m128[SIMDloop + 1];
arg1List = (__m128*) (((int) arg1List + 15) & ~15);

【讨论】:

  • 这行得通;非常感谢您的及时回复。不过,为什么要在数组大小上加 1?
  • 因为指针重新对齐可能会浪费 0 到 15 个前导字节。为了弥补这一点,您需要在另一端使用一些备用字节...
  • 好的,谢谢。出于好奇,您知道为什么这对于非常大的数组来说不是问题吗?
  • 我的猜测是,当您分配一个更大的数组(顺便说一句,它似乎是 2+ MB)时,堆分配器采用不同的代码路径并分配一些“新的大页面”来满足您的请求,这已经很好地对齐了。在较小的块上,对齐可能是 8 或更少,因为分配器似乎不处理 16 字节对齐。
猜你喜欢
  • 2013-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多