首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Visual上使用Keccak代码包

在Visual上使用Keccak代码包
EN

Stack Overflow用户
提问于 2018-11-04 01:16:26
回答 1查看 161关注 0票数 0

我下载了Keccak代码包(现在是XKCP ),因为我对它带来的所有特性感兴趣,我想在我的“项目”中使用它们,这就是我们将如何称呼它。

问题是我正在使用MicrosoftVisualStudioCommunity2017编写我的项目..。我会解释:

实际上,我试图在我的项目中实现Keyak,尤其是使用SIMD加速的Keyak实现。但是,KCP ( Keccak包)附带的代码是为GCC而设计的,而不是VS,因此,要在Visual上编译它是很困难的,而且主要是因为在Keyak实现中使用的宏中的(__m128d)和(__m128i)强制转换。GCC允许这种类型的强制转换,但是Visual不允许这样做,所以代码不能按原样工作,您必须使用_mm_castpd_si128和诸如此类的.

下面是我尝试过的:我用代码等效的代码替换了所有宏,并在GCC上使用了-E。事实上,在预处理器工作之后,我得到了代码,因此宏都是展开的,编写得很完整,然后我用它们的内在对应项替换了所有未被Visual接受的强制转换。最后,我可以在Visual上编译代码,但它仍然不能很好地运行。

以下是错误:

代码语言:javascript
复制
void KeccakP1600_Permute_12rounds(void *state)
{    
    //All the variables like Abae, Cae, Akimo etc... are ALL __m128i variables
    //state is an unsigned char[200]

    UINT64 *stateAsLanes = (UINT64*)state;
    Abae = _mm_load_si128((const __m128i *)&(stateAsLanes[0]));
    Aba = Abae;
    Abe = _mm_unpackhi_epi64(Abae, Abae);
    Cae = Abae;
    Abio = _mm_load_si128((const __m128i *)&(stateAsLanes[2]));
    Abi = Abio;
    Abo = _mm_unpackhi_epi64(Abio, Abio);
    Cio = Abio;
    Abu = _mm_loadl_epi64((const __m128i *)&(stateAsLanes[4]));
    Cua = Abu;
    Agae = _mm_loadu_si128((const __m128i *)&(stateAsLanes[5]));
    Aga = Agae;
    Abuga = _mm_unpacklo_epi64(Abu, Aga);
    Age = _mm_unpackhi_epi64(Agae, Agae);
    Abage = _mm_unpacklo_epi64(Aba, Age);
    Cae = _mm_xor_si128(Cae, Agae);
    Agio = _mm_loadu_si128((const __m128i *)&(stateAsLanes[7]));
    Agi = Agio;
    Abegi = _mm_unpacklo_epi64(Abe, Agi);
    Ago = _mm_unpackhi_epi64(Agio, Agio);
    Abigo = _mm_unpacklo_epi64(Abi, Ago);
    Cio = _mm_xor_si128(Cio, Agio);
    Agu = _mm_loadl_epi64((const __m128i *)&(stateAsLanes[9]));
    Abogu = _mm_unpacklo_epi64(Abo, Agu);
    Cua = _mm_xor_si128(Cua, Agu);
    Akae = _mm_load_si128((const __m128i *)&(stateAsLanes[10]));
    Aka = Akae;
    Ake = _mm_unpackhi_epi64(Akae, Akae);
    Cae = _mm_xor_si128(Cae, Akae);
    Akio = _mm_load_si128((const __m128i *)&(stateAsLanes[12]));
    Aki = Akio;
    Ako = _mm_unpackhi_epi64(Akio, Akio);
    Cio = _mm_xor_si128(Cio, Akio);
    Akuma = _mm_load_si128((const __m128i *)&(stateAsLanes[14]));
    Cua = _mm_xor_si128(Cua, Akuma);
    Ame = _mm_loadl_epi64((const __m128i *)&(stateAsLanes[16]));
    Akame = _mm_unpacklo_epi64(Aka, Ame);
    Cae = _mm_xor_si128(Cae, _mm_unpackhi_epi64(Akuma, Akame));
    Amio = _mm_loadu_si128((const __m128i *)&(stateAsLanes[17]));
    Ami = Amio;
    Akemi = _mm_unpacklo_epi64(Ake, Ami);
    Amo = _mm_unpackhi_epi64(Amio, Amio);
    Akimo = _mm_unpacklo_epi64(Aki, Amo);
    Cio = _mm_xor_si128(Cio, Amio);
    Amu = _mm_loadl_epi64((const __m128i *)&(stateAsLanes[19]));
    Akomu = _mm_unpacklo_epi64(Ako, Amu);
    Cua = _mm_xor_si128(Cua, Amu);
    Asase = _mm_load_si128((const __m128i *)&(stateAsLanes[20]));
    Cae = _mm_xor_si128(Cae, Asase);
    Asiso = _mm_load_si128((const __m128i *)&(stateAsLanes[22]));
    //Error here, last line. Access violation reading location.

问题是,当没有编译器优化,代码运行良好,没有错误,但一旦你打开全速优化,访问违规读取弹出。更别提这段代码是在GCC身上运行的,不管优化是什么。

您可能有一些解决阅读冲突的解决方案,甚至有些解决方案,说明如何将此"GCC代码“转换为Visual可编译代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-04 01:42:16

据推测,stateAsLanes是由16对齐的. _mm_load_si128((const __m128i *)&(stateAsLanes[22]));正在从一个错误对齐的地址执行128位对齐所需的负载.

你确定那是原始消息来源吗?无论如何,它需要是一个loadu,而不是load,才能告诉编译器它没有对齐。

在这段代码中,您没有使用_mm_castpd_si128,所以不清楚您更改了什么,也不清楚为什么要更改它。对于GCC/clang来说,它也被破坏了,即使在未优化的代码中也会使用movdqa

使用MSVC,它可能会中断优化,因为MSVC将负载折叠到内存操作数中,供以后的ALU指令使用;ICC,当MSVC和ICC必须使用独立的mov负载时,它们通常使用movdqu非对齐负载。这肯定会解释您所看到的行为,尽管它会使代码在Core 2上运行得比必要的慢。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53136953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档