小编use*_*983的帖子

快速sigmoid算法

sigmoid函数定义为

在此输入图像描述

我发现使用C内置函数exp()计算的值f(x)很慢.有没有更快的算法来计算值f(x)

algorithm neural-network

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

使用C++ 11复制和移动时避免代码重复

C++ 11"移动"是一个很好的功能,但我发现当与"复制"同时使用时,很难避免代码重复(我们都讨厌这个).下面的代码是我实现的一个简单的循环队列(不完整),两个push()方法几乎相同,除了一行.

我遇到过很多像这样的情况.任何想法如何避免这种代码重复而不使用宏?

===编辑===

在这个特定的例子中,重复的代码可以被重构并放入一个单独的函数中,但有时这种重构是不可用的或者不能轻易实现.

#include <cstdlib>
#include <utility>

template<typename T>
class CircularQueue {
public:
    CircularQueue(long size = 32) : size{size} {
        buffer = std::malloc(sizeof(T) * size);
    }

    ~CircularQueue();

    bool full() const {
        return counter.in - counter.out >= size;
    }

    bool empty() const {
        return counter.in == counter.out;
    }

    void push(T&& data) {
        if (full()) {
            throw Invalid{};
        }
        long offset = counter.in % size;
        new (buffer + offset) T{std::forward<T>(data)};
        ++counter.in;
    }

    void push(const T& data) {
        if (full()) { …
Run Code Online (Sandbox Code Playgroud)

c++ code-duplication move-semantics c++11

23
推荐指数
1
解决办法
1974
查看次数

C++绿色线程的堆栈分配

我正在做一些C++绿色线程的研究,大多数boost::coroutine2和类似的POSIX函数一样makecontext()/swapcontext(),并计划在其上实现一个C++绿色线程库boost::coroutine2.两者都需要用户代码为每个新函数/协同程序分配一个堆栈.

我的目标平台是x64/Linux.我希望我的绿色线程库适合一般用途,因此堆栈应该根据需要进行扩展(合理的上限很好,例如10MB),如果堆栈在未使用太多内存时可能会收缩,那就太好了(不需要) ).我还没有想出一个合适的算法来分配堆栈.

经过一些谷歌搜索,我自己想出了几个选项:

  1. 使用由编译器实现的拆分堆栈(gcc -fsplit-stack),但拆分堆栈有性能开销.由于性能原因,Go已经远离拆分堆栈.
  2. 分配一大块内存,mmap()希望内核足够聪明,可以保留未分配的物理内存,只在访问堆栈时分配.在这种情况下,我们受内核的支配.
  3. 保留一个大的内存空间mmap(PROT_NONE)并设置一个SIGSEGV信号处理程序.在信号处理程序中,当SIGSEGV由堆栈访问引起时(被访问的内存在保留的大内存空间内),分配所需的内存mmap(PROT_READ | PROT_WRITE).这是这种方法的问题:mmap()不是异步安全,不能在信号处理程序内部调用.它仍然可以实现,但非常棘手:在程序启动期间为内存分配创建另一个线程,并用于pipe() + read()/write()从信号处理程序向线程发送内存分配信息.

关于选项3的更多问题:

  1. 我不确定这种方法的性能开销,当内存空间由于成千上万的mmap()调用而极度分散时,内核/ CPU的性能/坏程度如何?
  2. 如果在内核空间中访问未分配的内存,这种方法是否正确?例如何时read()被召唤?

绿色线程的堆栈分配还有其他(更好的)选项吗?如何在其他实现中分配绿色线程堆栈,例如Go/Java?

c++ memory-management green-threads boost-coroutine

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

C++ 11 std :: thread和虚函数绑定

我遇到了一个奇怪的C++代码行为,不确定它是编译器错误还是我的代码的未定义/未指定的行为.这是代码:

#include <unistd.h>
#include <iostream>
#include <thread>

struct Parent {
    std::thread t;

    static void entry(Parent* p) {
        p->init();
        p->fini();
    }

    virtual ~Parent() { t.join(); }

    void start() { t = std::thread{entry, this}; }

    virtual void init() { std::cout << "Parent::init()" << std::endl; }
    virtual void fini() { std::cout << "Parent::fini()" << std::endl; }
};

struct Child : public Parent {
    virtual void init() override { std::cout << "Child::init()" << std::endl; }
    virtual void fini() override { std::cout << "Child::fini()" << …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading thread-safety race-condition

9
推荐指数
1
解决办法
1162
查看次数

OpenCL中的快速RGB => YUV转换

我知道以下公式可用于将RGB图像转换为YUV图像.在下面的公式中,R,G,B,Y,U,V都是8位无符号整数,中间值是16位无符号整数.

Y = ( (  66 * R + 129 * G +  25 * B + 128) >> 8) +  16  
U = ( ( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128  
V = ( ( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128
Run Code Online (Sandbox Code Playgroud)

但是当在OpenCL中使用该公式时,这是一个不同的故事.
1. 8位存储器写访问是可选扩展,这意味着一些OpenCL实现可能不支持它.
2.即使支持上述扩展,与32位写访问相比,它的速度也非常慢.

为了获得更好的性能,每4个像素将同时处理,因此输入为12个8位整数,输出为3个32位无符号整数(第一个代表4个Y样本,第二个代表4个Y样本,第二个代表4 U样品,最后一个代表4 V样品).

我的问题是如何直接从12个8位整数中获得这3个32位整数?是否有一个公式来获得这3个32位整数,或者我只需要使用旧公式得到12个8位整数结果(4 Y,4 U,4 V)并用位构造3个32位整数 - 运作?

rgb alignment yuv opencl

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

ld.so 替代品

我需要让我的 linux 可执行文件“编译一次,到处运行”。理论上是可以的,因为我的程序只使用非常基本的系统调用(网络 IO 和文件 IO 的系统调用)。在实践中,这是一个不同的故事:

我的开发平台是 Ubuntu 12.04,它有相当新的内核、glibc 和工具链。我首先尝试静态链接我的可执行文件,但该可执行文件拒绝在 centos 5(内核版本 2.6.18)上运行。如果可执行文件是动态链接的,动态加载程序 (ld.so) 将拒绝加载我的可执行文件。我什至尝试发布一个修改过的动态加载器(我将它修改为忽略内核版本),libc,libgcc_s,仍然不起作用,因为修改后的加载器总是尝试从系统加载 libc 并忽略随我的可执行。

我需要一个动态加载器,它会盲目加载我希望它加载的所有内容。有人知道 linux 上有这样的动态加载器吗?我不确定我是否朝着正确的方向前进,因此欢迎提出任何建议。

linux dynamic-linking

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

在Linux/GCC下将NULL指针访问转换为C++异常

有没有办法将NULL指针访问转换为Linux下的C++异常?类似于Java中的NullPointerException.我希望以下程序能够成功返回,而不是崩溃(假设编译器在编译期间无法找出此NULL指针访问):

class NullPointerException {};

void accessNullPointer(char* ptr) {
    *ptr = 0;
}

int main() {
    try {
        accessNullPointer(0);
    } catch (NullPointerException&) {
        return 1;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不期望任何标准的方法,因为C++下的NULL指针访问是未定义的 - 行为,只是想知道如何在x86_64 Linux/GCC下完成它.

我做了一些非常原始的研究,有可能:

  1. 当在Linux下访问NULL指针时,将生成SIGSEGV.
  2. 在SIGSEGV处理程序内部,程序的内存和寄存器信息将可用(如果sigaction()用于注册信号处理程序).如果程序被反汇编,也可以使用导致SIGSEGV的指令.
  3. 修改程序的内存和/或注册,并创建/伪造异常实例(可能通过调用低级展开库函数,如_Unwind_RaiseException等)
  4. 最后从信号处理程序返回,希望程序启动一个C++堆栈展开过程就像抛出正常异常一样.

以下是GCC手册页的引用(-fnon-call-exceptions):

生成允许捕获指令以抛出异常的代码.请注意,这需要在任何地方都不存在的特定于平台的运行时支持.此外,它只允许捕获指令抛出异常,即内存引用或浮点指令.它不允许从诸如"SIGALRM"之类的任意信号处理程序抛出异常.

看来这个"特定于平台的运行时"正是我想要的.任何人都知道这样的Linux/x86_64运行时?或者如果没有这样的运行时已经存在,请给我一些关于如何实现这样的运行时的信息?

我希望该解决方案也适用于多线程程序.

c++ linux gcc exception stack-unwinding

5
推荐指数
1
解决办法
417
查看次数

Kubernetes 在删除后不断生成 Pod

以下是用于创建部署的文件:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: kloud-php7
  namespace: kloud-hosting
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: kloud-php7
    spec:
      containers:
      - name: kloud-php7
        image: 192.168.1.1:5000/kloud-php7
      - name: kloud-nginx
        image: 192.168.1.1:5000/kloud-nginx
        ports:
        - containerPort: 80
Run Code Online (Sandbox Code Playgroud)

Deployment 和 Pod 工作正常,但是在删除 Deployment 和生成的 ReplicaSet 后,我​​无法永久删除 spawn Pod。如果删除旧的 Pod,则会创建新的 Pod。

kubernetes集群使用kargo创建,包含4个节点,运行CentOS 7.3,kubernetes 1.5.6版

知道如何解决这个问题吗?

kubernetes

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

通过 TCP 连接创建 VPN

我需要通过 TCP 连接创建一个虚拟 IP 网络。托管系统是Linux,带有TUN/TAP内核驱动,很容易接收和重新注入虚拟网络的IP包。

困难的部分是将接收到的 IP 数据包传输到另一台主机。由于一些非技术原因,我只能通过 TCP 协议而不是 UDP 传输数据包。通过 UDP 传输 IP 数据包很容易,但使用 TCP 就变得很棘手,原因如下:

UDP协议不支持重传/重排序,就像IP一样。因此,如果为每个接收到的虚拟 IP 数据包发送一个 UDP 数据包,内核 TCP/IP 协议栈仍会看到虚拟 IP 数据包丢失/重复/重新排序(这些是 TCP/IP 正常工作所必需的,如果这些“特性”丢失,虚拟网络上的 TCP 连接速度会受到影响)。如果 IP 数据包通过 TCP 传输,则所有必需的“功能”都将丢失,除非它们以某种方式进行模拟。

看来我必须在 TCP 连接上伪造某种数据包重复/丢失/重新排序,或者修补内核 TCP/IP 协议堆栈。这两种选择都不容易。

我的问题还有其他更简单的解决方案吗?还是我只是进入了一个完全错误的方向?我都是耳朵。

==== 更新 ====

我正在考虑使用原始 IP 套接字(它可以在仍然使用 TCP 数据包的同时轻松摆脱物理网络上的所有 TCP 重传/重新排序内容)来传输接收到的虚拟网络 IP 数据包。但是在接收主机上,如何只接收我感兴趣的数据包并将所有其他 IP 数据包返回到内核 TCP/IP 堆栈?

linux vpn tcp tun-tap

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