我的应用程序中有一个EXC_ARM_DA_ALIGN崩溃.这是Xcode标记为"恶意"的代码.在模拟器上我没有这个崩溃,只在设备上,所以我认为这是一个内存对齐问题.有谁知道如何修复此代码?非常感谢.
-(int) Save:(void*) pBuf {
int nNeedSize = sizeof(fType) + sizeof(sizeBrush) + sizeof(nBrushType) + sizeof(rcImage) + sizeof(count) + sizeof(data[0]) * count;
if (pBuf == nil)
return nNeedSize;
*(NSInteger*)pBuf = count; pBuf += sizeof(count);
*(BOOL*)pBuf = fType; pBuf += sizeof(fType);
(*(CGSize*)pBuf).width = sizeBrush.width;
(*(CGSize*)pBuf).height = sizeBrush.height;
pBuf += sizeof(sizeBrush);
*(NSInteger*)pBuf = nBrushType; pBuf += sizeof(nBrushType);
(*(CGRect*)pBuf).size.width = rcImage.size.width;
(*(CGRect*)pBuf).size.height = rcImage.size.height;
(*(CGRect*)pBuf).origin.x = rcImage.origin.x;
(*(CGRect*)pBuf).origin.y = rcImage.origin.y;
pBuf += sizeof(rcImage);
for (int i = 0; i < count; i++)
{
(*(CGPoint*)pBuf).x …Run Code Online (Sandbox Code Playgroud) 在我的代码中,我必须处理websocket数据包的"取消屏蔽",这实际上意味着对任意长度的未对齐数据进行异或.感谢SO(Websocket数据取消屏蔽/多字节xor)我已经发现如何(希望)使用SSE2/AVX2扩展加速这一点,但现在看一下,在我看来,我对未对齐数据的处理完全是sub -最佳.有没有办法优化我的代码或者至少使它具有相同的性能更简单,或者我的代码是否已经表现最佳?
这是代码的重要部分(对于这个问题,我假设数据总是至少足以运行一次AVX2循环,但同时它最多只能运行几次):
// circular shift left for uint32
int cshiftl_u32(uint32_t num, uint8_t shift) {
return (num << shift) | (num >> (32 - shift));
}
// circular shift right for uint32
int cshiftr_u32(uint32_t num, uint8_t shift) {
return (num >> shift) | (num << (32 - shift));
}
void optimized_xor_32( uint32_t mask, uint8_t *ds, uint8_t *de ) {
if (ds == de) return; // zero data len -> nothing to do
uint8_t maskOffset = 0;
// process …Run Code Online (Sandbox Code Playgroud) 我有一个静态结构数组:
struct CommandStruct
{
char* data;
unsigned ans_size;
};
static const CommandStruct commands[] =
{
{ "Some literal", 28 },
{ "Some other literal", 29 },
{ "Yet another literal", 8 },
};
Run Code Online (Sandbox Code Playgroud)
我希望字符串是 16 字节对齐的。可以直接实现吗?我可能会单独定义每个文字,例如__declspec(align(16)) static const char some_command_id[] = "my literal",但这很混乱。我需要在一个代码块中进行所有初始化。
某些CPU架构(x86除外)不喜欢在未对齐的地址读取和写入多字节数字,以至于在检测到这种情况时会引发SIGBUS异常,并迫使程序员按字节顺序手动完成所有操作.虽然对于需要这个的平台可能无法做任何事情,但检查对齐并在允许未对齐访问的平台(例如x86)上执行逐字节操作将是愚蠢的.问题是:C/C++编译器是否定义了一个表示对齐要求的常量?
目前,我正在使用这个:
#if defined(_M_IX86) | defined(__i386) | defined(__i386__) | defined(i386) | defined(_X86_)
// Unaligned access is allowed.
#elif defined(_M_X64) | defined(__x86_64__) | defined(__x86_64) | defined(__amd64) | defined(__amd64__) | defined(_M_AMD64)
// Unaligned access is allowed.
#else
#define ALIGNED_ACCESS_ONLY
#endif
Run Code Online (Sandbox Code Playgroud)
但它看起来太"家酿":它不是指示当前硬件平台的实际属性,而是描述了我自己对x86-32和x86-64的考虑以及这些平台最常用的常量名称.
当在x86上运行的算法上尝试调试随机40x性能下降时,我几乎疯了,因为算法大量使用Inter64.CompareExchange和Int64.
我终于隔离了这个问题,只有当所说的Int64不是8字节对齐时才会发生.
无论我如何在StructLayout中显式定位字段,它都依赖于堆上外部对象的基地址.在x86上,基地址将是4字节对齐或8字节对齐.
我想到定义一个12字节的结构并根据对齐将Int64设置为偏移0或偏移4,但这有点像hacky.
c#中有一个很好的做法,用于在x86中对Int64执行互锁操作,以确保正确对齐吗?
编辑
代码可以在这里找到:https: //github.com/akkadotnet/akka.net/pull/1569#discussion-diff-47997213R520
它是一个基于Clr ThreadPool的线程池实现.问题是关于将自定义信号量的状态存储在8字节结构中并使用InterlockedCompareExchange64进行修改.
出于某种原因,我的一个函数正在调用movaps带有未对齐参数的 SSE 指令,这会导致崩溃。它发生在函数的第一行,其余的都需要在那里发生崩溃,但为了清楚起见省略了。
Vec3f CrashFoo(
const Vec3f &aVec3,
const float aFloat,
const Vec2f &aVec2)
{
const Vec3f vecNew =
Normalize(Vec3f(aVec3.x, aVec3.x, std::max(aVec3.x, 0.0f)));
// ...
}
Run Code Online (Sandbox Code Playgroud)
这是我从调试主要调用它的方式:
int32_t main(int32_t argc, const char *argv[])
{
Vec3f vec3{ 0.00628005248f, -0.999814332f, 0.0182171166f };
Vec2f vec2{ 0.947231591f, 0.0522233732f };
float floatVal{ 0.010f };
Vec3f vecResult = CrashFoo(vec3, floatVal, vec2);
return (int32_t)vecResult.x;
}
Run Code Online (Sandbox Code Playgroud)
这是从CrashFoo函数开头到崩溃行的反汇编:
00007FF7A7DC34F0 mov rax,rsp
00007FF7A7DC34F3 mov qword ptr [rax+10h],rbx
00007FF7A7DC34F7 push rdi
00007FF7A7DC34F8 sub rsp,80h
00007FF7A7DC34FF movaps xmmword …Run Code Online (Sandbox Code Playgroud) 是否有任何安全的方法可以将整数转换为结构?
举个例子:
struct Colour
{
uint8_t A;
uint8_t R;
uint8_t G;
uint8_t B;
};
Run Code Online (Sandbox Code Playgroud)
我转换为整数或从整数转换:
uint32_t myInteger
Colour* myColour = reinterpret_cast<Colour*>(&myInteger);
uint32_t* myInteger2 = reinterpret_cast<uint32_t*>(myColour);
Run Code Online (Sandbox Code Playgroud)
如果我的结构被填充,那么这将不起作用,有什么方法可以保证它有效吗?
我知道这可能不是标准的,但我更喜欢支持主要编译器(Visual Studio 和 GCC)而不是一些位移解决方法,这里已经回答了:Type cast struct to integer c++。
考虑以下 C 代码:
#include <stdint.h>
void func(void) {
uint32_t var = 0;
return;
}
Run Code Online (Sandbox Code Playgroud)
-O0GCC 4.7.2 为上述代码生成的未优化(即:选项)汇编代码是:
func:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $0, -4(%ebp)
nop
leave
ret
Run Code Online (Sandbox Code Playgroud)
根据堆栈对准要求所述的系统V ABI,堆栈必须由16个字节每之前对准call指令(该堆栈边界是默认的16个字节时不与该选项改变-mpreferred-stack-boundary)。因此,在函数调用之前,ESP 模16的结果必须为零。
记住这些堆栈对齐要求,我假设在执行leave指令之前以下堆栈的状态表示是正确的:
Size (bytes) Stack ESP mod 16 Description
-----------------------------------------------------------------------------------
| . . . |
------------------........0 at func call
4 | return address |
------------------.......12 at func entry
4 | saved …Run Code Online (Sandbox Code Playgroud) 我非常简单的代码如下所示
#include <iostream>
#include <stdalign.h>
int main() {
char array_char[2] = {'a', 'b'};
float array_float[2] = {1, 2};
std::cout << "alignof(array_char): " << alignof(array_char) << std::endl;
std::cout << "alignof(array_float): " << alignof(array_float) << std::endl;
std::cout << "address of array_char: " << (void *) array_char << std::endl;
std::cout << "address of array_float: " << array_float << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这段代码的输出是
alignof(array_char): 1
alignof(array_float): 4
array_char 的地址:0x7fff5e8ec580
array_float 的地址:0x7fff5e8ec570
alignof算子的结果在意料之中,但是两个数组的真实地址并不一致。无论我尝试了多少次,地址总是 16 字节对齐。
我在 Ubuntu 16.04 和 Intel CORE i5 第 7 代 …
如何在C中获取CPU的内存粒度?
假设我想分配一个数组,其中所有元素都正确内存对齐。我可以将每个元素填充到特定大小 N 来实现这一点。我怎么知道N的值?
注意:我正在尝试创建一个内存池,其中每个插槽都是内存对齐的。任何建议将不胜感激。
memory-alignment ×10
c++ ×4
c ×3
x86 ×2
abi ×1
assembly ×1
avx2 ×1
c# ×1
crash ×1
disassembly ×1
gcc ×1
granularity ×1
interlocked ×1
iphone ×1
objective-c ×1
optimization ×1
platform ×1
portability ×1
sse ×1
sse2 ×1