小编Jef*_*eff的帖子

如何编写信号处理程序来捕获SIGSEGV?

我想写一个信号处理程序来捕获SIGSEGV.我使用保护内存块进行读写

char *buffer;
char *p;
char a;
int pagesize = 4096;

mprotect(buffer,pagesize,PROT_NONE)
Run Code Online (Sandbox Code Playgroud)

这可以保护从缓冲区开始的内存大小字节的内存,防止任何读取或写入.

其次,我尝试读取内存:

p = buffer;
a = *p 
Run Code Online (Sandbox Code Playgroud)

这将生成一个SIGSEGV,我的处理程序将被调用.到现在为止还挺好.我的问题是,一旦调用处理程序,我想通过这样做来改变内存的访问写入

mprotect(buffer,pagesize,PROT_READ);
Run Code Online (Sandbox Code Playgroud)

并继续正常运行我的代码.我不想退出该功能.在将来写入相同内存时,我想再次捕获信号并修改写入权限,然后记录该事件.

这是代码:

#include <signal.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>

#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)

char *buffer;
int flag=0;

static void handler(int sig, siginfo_t *si, void *unused)
{
    printf("Got SIGSEGV at address: 0x%lx\n",(long) si->si_addr);
    printf("Implements the handler only\n");
    flag=1;
    //exit(EXIT_FAILURE);
}

int main(int argc, char *argv[])
{ …
Run Code Online (Sandbox Code Playgroud)

c linux system-calls mprotect signal-handling

68
推荐指数
4
解决办法
7万
查看次数

减少OpenMP中的数组

我试图并行化以下程序,但不知道如何减少数组.我知道不可能这样做,但还有其他选择吗?谢谢.(我添加了对m的减少,这是错误的,但希望就如何做到这一点提出建议.)

#include <iostream>
#include <stdio.h>
#include <time.h>
#include <omp.h>
using namespace std;

int main ()
{
  int A [] = {84, 30, 95, 94, 36, 73, 52, 23, 2, 13};
  int S [10];

  time_t start_time = time(NULL);
  #pragma omp parallel for private(m) reduction(+:m)
  for (int n=0 ; n<10 ; ++n ){
    for (int m=0; m<=n; ++m){
      S[n] += A[m];
    }
  }
  time_t end_time = time(NULL);
  cout << end_time-start_time;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ parallel-processing openmp reduction

27
推荐指数
3
解决办法
3万
查看次数

模板__host__ __device__调用主机定义的函数

在实现CUDA代码期间,我经常需要一些实用程序函数,这些函数将从设备和主机代码中调用.所以我将这些函数声明为__host__ __device__.这是可以的,#ifdef CUDA_ARCH可以处理可能的设备/主机不兼容性.

当效用函数被模板化时出现问题,即.通过一些仿函数类型.如果模板实例调用__host__函数,我会收到此警告:

calling a __host__ function from a __host__ __device__ function is not allowed
      detected during instantiation of "int foo(const T &) [with T=HostObject]" 
Run Code Online (Sandbox Code Playgroud)

我知道的唯一解决方案是定义函数两次 - 一次用于设备,一次用于具有不同名称的主机代码(我不能重载__host__ __device__).但这意味着存在代码重复和所有其他__host__ __device__将调用它的函数,也必须定义两次(甚至更多的代码重复).

简化示例:

#include <cuda.h>
#include <iostream>

struct HostObject {
    __host__ 
    int value() const { return 42; }
};

struct DeviceObject {
    __device__ 
    int value() const { return 3; }
};

template <typename T> 
__host__ __device__ 
int foo(const T …
Run Code Online (Sandbox Code Playgroud)

cuda

12
推荐指数
1
解决办法
4521
查看次数

GPU上浮点数的划分与CPU上的浮点数划分不同

当我在GPU上划分两个浮点数时,结果是0.196405.当我在CPU上划分它们时,结果是0.196404.使用计算器的实际值是0.196404675.如何在GPU和CPU上进行划分?

cuda gpu

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

如何用`decltype`和继承规避英特尔C++编译器的问题?

今天我非常惊讶地发现英特尔的icpc(版本14.0.2,使用std=c++0x)无法编译以下代码段.


#include <type_traits>

namespace traits_tests {
  template<typename>
  struct sfinae_true : std::true_type {};

  template<typename T>
  static auto value_type(int) -> sfinae_true<typename T::value_type>;
  template<typename T>
  static auto value_type(void*) -> std::false_type;
}

template<typename C>
struct has_value_type
  : decltype(traits_tests::value_type<C>(0)) {};
Run Code Online (Sandbox Code Playgroud)

抱怨最后一行:

inc/traits.h(258): error: expected an identifier
    : decltype(traits_tests::value_type<C>(0)) {};
      ^
Run Code Online (Sandbox Code Playgroud)

代码适用于clanggcc.

我真的不想完全重写,以使它与有缺陷的编译器一起工作(为什么商业编译器总是有缺陷?).

  • 是否有一种更简单的方法,而不是完全不同的SFINAE模式,以使其适用icc

编辑:是的,我知道icc支持decltype一段时间以来.但在上述特定背景下,icc未能支持它.另请注意,使用std=c++11而不是std=c++0x没有区别.

c++ inheritance icc decltype c++11

6
推荐指数
1
解决办法
431
查看次数

Intel指令的LOCK前缀.有什么意义?

我阅读了英特尔手册,发现指令有一个锁定前缀,可以防止处理器同时写入同一个内存位置.我很兴奋.我想它可以用作硬件互斥.所以我写了一段代码来拍摄.结果非常令人沮丧.锁不支持MOV或LEA指令.手册说LOCK仅支持ADD,ADC,AND,BTC,BTR,BTS,CMPXCHG,CMPXCH8B,DEC,INC,NEG,NOT,OR,SBB,SUB,XOR,XADD和XCHG.而且,如果LOCK前缀与这些指令之一一起使用并且源操作数是存储器操作数,则可以生成未定义的操作码异常(#UD).

我想知道为什么这么多限制,如此多的限制使得LOCK看起来毫无用处.我不能用它来保证一般的写操作没有脏数据或并行引起的其他问题.

例如,我在C中编写了代码++(*p).p是指向共享内存的指针.相应的程序集如下:

movl    28(%esp), %eax
movl    (%eax), %eax
leal    1(%eax), %edx
movl    28(%esp), %eax
movl    %edx, (%eax)
Run Code Online (Sandbox Code Playgroud)

我在"movl"和"leal"之前添加了"lock",但是处理器抱怨"无效指令".:-(我想将序列化写操作的唯一方法是使用软件互斥,对吧?

c linux parallel-processing assembly intel

5
推荐指数
2
解决办法
9913
查看次数

如何获取MPI中的物理机数量

我可以MPI_Comm_size用来获得总处理器的数量.但是如何才能获得真实物理机的数量呢?

c fortran mpi

5
推荐指数
2
解决办法
426
查看次数

对C99可变长度数组(VLA)使用限制限定符

我正在探索如何基于函数签名在C99中简单循环的不同实现自动矢量化。

这是我的代码:

/* #define PRAGMA_SIMD _Pragma("simd") */
#define PRAGMA_SIMD

#ifdef __INTEL_COMPILER
#define ASSUME_ALIGNED(a) __assume_aligned(a,64)
#else
#define ASSUME_ALIGNED(a)
#endif

#ifndef ARRAY_RESTRICT
#define ARRAY_RESTRICT
#endif

void foo1(double * restrict a, const double * restrict b, const double * restrict c) 
{ 
    ASSUME_ALIGNED(a);
    ASSUME_ALIGNED(b);
    ASSUME_ALIGNED(c);
    PRAGMA_SIMD
    for (int i = 0; i < 2048; ++i) {
        if (c[i] > 0) {
            a[i] = b[i];
        } else {
            a[i] = 0.0;
        } 
    }
}

void foo2(double * restrict a, const double * restrict b, …
Run Code Online (Sandbox Code Playgroud)

simd c99 variable-length-array restrict-qualifier auto-vectorization

4
推荐指数
1
解决办法
747
查看次数