小编Dan*_*ski的帖子

SIMD/SSE:如何检查所有向量元素是否为非零

我需要检查所有向量元素是否为非零.到目前为止,我找到了以下解 有一个更好的方法吗?我在Linux/x86_64上使用gcc 4.8.2,指令直到SSE4.2.

typedef char ChrVect __attribute__((vector_size(16), aligned(16)));

inline bool testNonzero(ChrVect vect)
{
    const ChrVect vzero = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    return (0 == (__int128_t)(vzero == vect));
}
Run Code Online (Sandbox Code Playgroud)

更新:上面的代码被编译为以下汇编代码(当编译为非内联函数时):

movdqa  %xmm0, -24(%rsp)
pxor    %xmm0, %xmm0
pcmpeqb -24(%rsp), %xmm0
movdqa  %xmm0, -24(%rsp)
movq    -24(%rsp), %rax
orq -16(%rsp), %rax
sete    %al
ret
Run Code Online (Sandbox Code Playgroud)

c c++ gcc simd vectorization

10
推荐指数
1
解决办法
1175
查看次数

OpenSSL和信号

套接字函数喜欢sendreceive可以通过信号中断.因此,需要一些额外的代码,例如检查errno == EINTR.这在相应的手册页上进行了描述.

我不知道,当OpenSSL的功能使用,例如这是如何工作的SSL_write,SSL_read.他们的手册没有说明信号.我也尝试谷歌这个,但没有运气.你知道OpenSSL是否在内部处理信号,还是需要一些额外的代码?如果是,如何检查函数调用是否被信号中断?

更新:

看起来OpenSSL不处理重试.它只在BIO对象上设置"should retry"标志.所以我需要使用这样的东西来检测呼叫是否被中断并且需要重试:

int result = SSL_write(ssl, buff, length);
if ((result < 0) && BIO_should_retry(SSL_get_wbio(ssl)))
    // need to retry

int result = SSL_read(ssl, buff, length);
if ((result < 0) && BIO_should_retry(SSL_get_rbio(ssl)))
    // need to retry
Run Code Online (Sandbox Code Playgroud)

c c++ linux openssl signals

8
推荐指数
1
解决办法
1407
查看次数

SSE:跨越页面边界的未对齐加载和存储

我在某处读到了在页面边界旁边执行未对齐的加载或存储之前(例如使用_mm_loadu_si128/ _mm_storeu_si128intrinsics),代码应首先检查整个向量(在这种情况下是16个字节)是否属于同一页面,如果不是,则切换到非向量指令.我知道如果下一页不属于进程,则需要这样做以防止coredump.

但是,如果两个页面都属于进程(例如,它们是一个缓冲区的一部分,并且我知道该缓冲区的大小),该怎么办?我写了一个小的测试程序,它执行了未对齐的加载和跨越页面边界的存储,并没有崩溃.在这种情况下,我是否必须始终检查页面边界,还是足以确保我不会溢出缓冲区?

环境:Linux,x86_64,gcc

c linux sse x86-64 memory-alignment

8
推荐指数
1
解决办法
688
查看次数

如何检测外部"C"是否有效

我试图找到#include放在extern C区块内的所有地方.可以使用预处理器检查这个吗?我想在我的头文件中添加这样的内容:

#ifdef EXTERN_C_IS_IN_EFFECT
#error File included from extern "C" block!
#endif
Run Code Online (Sandbox Code Playgroud)

我也在寻找其他在这种情况下编译失败的方法,例如使用一些特殊属性.我使用的是gcc 4.4.7.

我定义了以下宏,然后在需要防止包含在extern C块中的每个头中使用它:

#define ASSERT_NO_EXTERN_C void assert_no_extern_c(int); void assert_no_extern_c(double);
Run Code Online (Sandbox Code Playgroud)

c extern c-preprocessor

6
推荐指数
2
解决办法
659
查看次数

如何解释这个C++类型?

今天我正在帮助跟踪不正确的代码片段(funcintparam 声明,但int*作为第二个参数传递给std::thread构造函数):

#include <thread>

void func(int);
int* ptr;

void start()
{
    std::thread t = std::thread(func, ptr);
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用gcc 5.3.0编译它时,它打印了以下类型的错误消息:

class std::result_of<void (*(int*))(int)>
Run Code Online (Sandbox Code Playgroud)

现在我想知道如何解释作为参数传递的类型class std::result_of<>.它类似于指向函数的指针(在这种情况下void(*)(int)),但(int*)括号中有额外的后星.如何解释这种类型?

c++ gcc types

6
推荐指数
2
解决办法
255
查看次数

如何在块中生成组合

我有算法,它对输入元素的每个组合执行计算,例如,对于100个元素集中的每个5元素子集.我将它移植到GPU,现在我准备好它的初始版本.为了加快速度,我想从本地内存加载数据,这是有限的(例如32KB)并且可以容纳20个输入元素中的100个.因此我必须以某种方式对我的工作进行分区并以块的形式生成组合.现在这是困难的部分,如何做到这一点.最有可能的是,我必须先为20个元素加载数据,然后对这20个元素的5个元素子集进行计算.在此之后,我将不得不用新的替换它们中的一些(或全部)并对它们进行计算,然后冲洗并重复.你能告诉我如何在本地内存中选择替换元素,以避免重复工作?到目前为止,我得出的结论是,我必须立即更换至少16个,以避免重复的工作问题.

编辑:这里是从5个元素中生成2元素组合的示例.以下是所有可能案例的完整列表:

1, 2
1, 3
1, 4
1, 5
2, 3
2, 4
2, 5
3, 4
3, 5
4, 5
Run Code Online (Sandbox Code Playgroud)

GPU上的本地内存有限 - 假设它只能容纳3个元素.因此,我必须以某种方式将我的问题分成3个元素中的2个元素的组合.我必须重复多次,直到我从上面的列表中获得所有组合.作为第一步,我可以将元素1,2,3加载到本地内存中,因此我将得到以下组合:

1, 2
1, 3
2, 3
Run Code Online (Sandbox Code Playgroud)

现在我必须加载另一组元素并为它们计算组合.它可以是1,4,5.它将产生以下组合:

1, 4
1, 5
4, 5
Run Code Online (Sandbox Code Playgroud)

另一方面,设置1,2,4无效 - 这将导致重复组合:

1, 2 // duplicate
1, 4 // ok, new
2, 4 // ok, new
Run Code Online (Sandbox Code Playgroud)

在此步骤之后,还有4个要生成的组合(列表如下).算法必须能够从3个元素中生成另一个2元素组合,并以某种方式处理最后(第10个)组合.

2, 4
2, 5
3, 4
3, 5
Run Code Online (Sandbox Code Playgroud)

通过以这种方式分割工作,我将能够使用有限的本地存储器处理原始输入集的所有组合,该存储器只能容纳其中的一部分.

algorithm combinations

5
推荐指数
0
解决办法
163
查看次数

如何将函数参数标记为输出

C#允许将函数参数标记为仅输出:

void func(out int i)
{
    i = 44;
}
Run Code Online (Sandbox Code Playgroud)

是否有可能在C/C++中做类似的事情?这可以改善优化.另外应该使警告静音"错误:'myVar'可以在此函数中未初始化使用",当变量未初始化然后传递给函数作为输出参数时.

我使用gcc/g ++(目前是4.4.7)来编译我的代码.

编辑:我知道指针和引用,这不是我要找的.我需要这样的东西:

void func(int* __attribute__((out)) i)
{
    *i = 44;
}

void func2()
{
    int myVal; // gcc will print warning: 'myVar' may be used uninitialized in this function
    func(&myVal);
    //...
}
Run Code Online (Sandbox Code Playgroud)

编辑2:需要一些额外的代码来重现警告"'myVar'可能在此函数中未初始化使用".另外,你必须将-Wall -O1传递给gcc.

void __attribute__((const)) func(int* i)
{
    *i = 44;
}

int func2()
{
    int myVal; // warning here
    func(&myVal);
    return myVal;
}
Run Code Online (Sandbox Code Playgroud)

c c++ attributes gcc out

3
推荐指数
1
解决办法
4001
查看次数