select、poll、epoll的原理与区别
select、poll、epoll的原理与区别
select 同步多路IO复用
时间复杂度:O(n)
fd_set(监听的端口个数):32位机默认是1024个,64位机默认是2048。
缺点:
(1)单进程可以打开fd有限制;
(2)对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低;
(2)用户空间和内核空间的复制非常消耗资源
poll
同步多路IO复用
调用过程和select类似
时间复杂度:O(n)
其和select不同的地方:采用链表的方式替换原有fd_set数据结构,而使其没有连接数的限制。
epoll
同步多路IO复用
时间复杂度:O(1)
epoll的工作方式
epoll的两种工作方式:1.水平触发(LT)2.边缘触发(ET) LT模式:若就绪的事件一次没有处理完要做的事件,就会一直去处理。即就会将没有处理完的事件继续放回到就绪队列之中(即那个内核中的链表),一直进行处理。 ET模式:就绪的事件只能处理一次,若没有处理完会在下次的其它事件就绪时再进行处理。而若以后再也没有就绪的事件,那么剩余的那部分数据也会随之而丢失。 由此可见:ET模式的效率比 ...
CUDA之卷积
卷积main.cu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116#include <stdio.h>#define HANDLE_ERROR(err) (handleError(err, __FILE__, __LINE__))void handleError(cudaError_t err, const char *file, int line) { if (err != cudaSuccess) { printf("%s in %s at line %d \n", cudaGetErrorStr ...
CUDA之数组相加
数组相加main.cu
123456789101112131415161718192021222324252627282930313233343536373839#include <stdio.h>__global__ void sum(float *a, float *b) { int t_id = threadIdx.x; __shared__ float sData[16]; sData[t_id] = a[t_id]; __syncthreads(); for(int i = 8; i > 0; i /= 2) { if(t_id < i) { sData[t_id] = sData[t_id] + sData[t_id + i]; } __syncthreads(); } if(t_id == 0) { b[0] = sData[0]; }}int main(int argc, char *argv[]){ fl ...
CUDA之基本运算
基本运算main.cu
123456789101112131415161718192021222324252627282930313233343536373839404142434445#include <stdio.h>__global__ void add(int *a, int *b, int *c, int num) { int i = threadIdx.x; if(i < num) { c[i] = a[i] + b[i]; }}int main(int argc, char *argv[]){ int num = 10; int a[num], b[num], c[num]; int *a_gpu, *b_gpu, *c_gpu; for(int i = 0; i < num; i ++) { a[i] = i; b[i] = i + i; } cudaMalloc((void **) &a_gpu, num * sizeof(int) ...
CUDA之GPU运算简单步骤
GPU运算简单步骤main.cu
123456789101112131415161718192021222324252627282930313233343536373839#include <iostream>using namespace std;__global__ void vector_add(float *vec1, float *vec2, float *vec_out, int length) { int tid = threadIdx.x; if(tid < length) { vec_out[tid] = vec1[tid] + vec2[tid]; }}int main(int argc, char *argv[]){ const int length = 16; // 数组长度为16 float a[length], b[length], c[length]; // ...
CUDA获取GPU信息
获取GPU信息main.cu
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364#include <stdio.h>#define HANDLE_ERROR(err) (handle_error(err, __FILE__, __LINE__))__global__ void kernelFunc(float *a) { a[threadIdx.x] = 1; }static void handle_error(cudaError_t err, const char *file, int line) { if (err != cudaSuccess) { printf("%s in %s at line %d\n", cudaGetErrorString(err), file, line); exit(EXIT_FA ...
C++之std::move和std::forward
C++11 std::move和std::forward引入的新规则规则1(引用折叠规则):如果间接的创建一个引用的引用,则这些引用就会“折叠”。在所有情况下(除了一个例外),引用折叠成一个普通的左值引用类型。一种特殊情况下,引用会折叠成右值引用,即右值引用的右值引用, T&& &&。即
X& &、X& &&、X&& &都折叠成X&
X&& &&折叠为X&&
规则2(右值引用的特殊类型推断规则):当将一个左值传递给一个参数是右值引用的函数,且此右值引用指向模板类型参数(T&&)时,编译器推断模板参数类型为实参的左值引用,如
12345template<typename T> void f(T&&);int i = 42;f(i)
上述的模板参数类型T将推断为int&类型,而非int。
若将规则1和规则2结合起来,则意味着可以传递一个左值int i给f,编译器将推断出T的类型为i ...
C++之实现C++的智能指针
实现C++的智能指针回顾下面这个类:
12345678910111213class shape_wrapper {public: explicit shape_wrapper( shape* ptr = nullptr) : ptr_(ptr) {} ~shape_wrapper() { delete ptr_; } shape* get() const { return ptr_; }private: shape* ptr_;};
这个类可以完成智能指针的最基本的功能:对超出作用域的对象进行释放。但它缺了点东西:
这个类只适用于 shape 类
该类对象的行为不够像指针
拷贝该类对象会引发程序行为异常
下面我们来逐一看一下怎么弥补这些问题。
模板化和易用性要让这个类能够包装任意类型的指针,我们需要把它变成一个类模板。这实际上相当容易:
12345678910111213template <typename T>class smart_ptr {pu ...
C++之堆、栈、RAII:C++里该如何管理资源
堆、栈、RAII:C++里该如何管理资源?基本概念堆:英文是 heap,在内存管理的语境下,指的是动态分配内存的区域。这个堆跟数据结构里的堆不是一回事。这里的内存,被分配之后需要手工释放,否则就会造成内存泄漏。
C++ 标准里一个相关概念是自由存储区,英文是 free store,特指使用 new 和 delete 来分配和释放内存的区域。一般而言,这是堆的一个子集:
new 和 delete 操作的区域是 free store
malloc 和 free 操作的区域是 heap
但 new 和 delete 通常底层使用 malloc 和 free 来实现,所以 free store 也是 heap。
栈:英文是 stack,在内存管理的语境下,指的是函数调用过程中产生的本地变量和调用数据的区域。这个栈和数据结构里的栈高度相似,都满足“后进先出”(last-in-first-out 或LIFO)。
RAII:完整的英文是 Resource Acquisition Is Initialization,是 C++ 所特有的资源管理方式。有少量其他语言,如 D、Ada 和 Rust 也 ...
C++之type_traits型别
__type_traits型别traits是为了将迭代器没能完善的原生指针, traits用特化和偏特化编程来完善. 这一篇准备探讨__type_traits, 为了将我们在空间配置器里面的提过的__true_type和false_type进行解答. 而type_traits型别对我们STL的效率又有什么影响, 有什么好处?
__type_traits介绍前面介绍的Traits技术在STL中弥补了C++模板的不足,但是Traits技术只是用来规范迭代器,对于迭代器之外的东西没有加以规范。因此,SGI将该技术扩展到迭代器之外,称为__type_traits。iterator_traits是萃取迭代器的特性,而__type_traits是萃取型别的特性。萃取的型别如下:
是否具备non-trivial default ctor?
是否具备non-trivial copy ctor?
是否具备non-trivial assignment operator?
是否具备non-trivial dtor?
是否为POD(plain old data)型别?
其中non-trivial意指非默认 ...





