linux下通过按照如下修改.ssh/config设置账号密码,并 ssh -vT [email protected],成功后输出Hi Kirrito-k423! You've successfully authenticated, but GitHub does not provide shell access.。
Host * # Win报错取消下面三行 getpeername failed: Not a socket getsockname failed: Not a socket ControlMaster auto ControlPath /tmp/sshcontrol-%C ControlPersist 1d ServerAliveInterval 30
Windows PowerShell 平台
假如是windows下,如果安装了git bash,会有connect.exe的程序
配置如下[^1]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Host github.com User git Port 22 Hostname github.com # 注意修改路径为你的路径 IdentityFile "C:\Users\Administrator\.ssh\id_rsa" TCPKeepAlive yes # 这里的 -a none 是 NO-AUTH 模式,参见 https://bitbucket.org/gotoh/connect/wiki/Home 中的 More detail 一节 ProxyCommand E:\\commonSoftware\\Git\\mingw64\\bin\\connect.exe -S 127.0.0.1:7890 -a none %h %p
Host ssh.github.com User git Port 443 Hostname ssh.github.com # 注意修改路径为你的路径 IdentityFile "C:\Users\Administrator\.ssh\id_rsa" TCPKeepAlive yes
There are tons of identical solutions over the internet for defining proxy tunnel for git’s downloads like this one, which all is by setting git’s https.proxy & http.proxy config. but those answers are not working when you try to clone/push/pull etc. over the ssh protocol!
For example, by setting git config --global https.proxy socks5://127.0.0.1:9999 when you try to clone git clone [email protected]:user/repo.git it does not go through the defined sock5 tunnel!
// constructors used in the same order as described above: std::string s1; std::string s2(s0); std::string s3(s0, 8, 3); std::string s4("A character sequence"); std::string s5("Another character sequence", 12); std::string s6a(10, 'x'); std::string s6b(10, 42); // 42 is the ASCII code for '*' std::string s7(s0.begin(), s0.begin()+7);
//output s1: s2: Initial string s3: str s4: A character sequence s5: Another char s6a: xxxxxxxxxx s6b: ********** s7: Initial
读取空格分割的
1 2 3 4 5
stringstream txt(s); string word; while(txt>>word){ // to do }
增
插入
使用insert()在指向位置的右边插入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// inserting into a string #include<iostream> #include<string>
std::string str="to be question"; std::string str2="the "; std::string str3="or not to be"; std::string::iterator it;
// used in the same order as described above: str.insert(6,str2); // to be (the )question str.insert(10,"to be "); // to be not (to be )that is the question it = str.insert(str.begin()+5,','); // to be(,) not to be: that is the question str.insert(6,str3,3,4); // to be (not )the question str.insert(10,"that is cool",8); // to be not (that is )the question str.insert(str.end(),3,'.'); // to be, not to be: that is the question(...) str.insert(15,1,':'); // to be not to be(:) that is the question // ??? str.insert (it+2,str3.begin(),str3.begin()+3); // (or )
尾部插入
插入char不同的方法
1 2 3 4 5 6 7 8 9 10 11 12 13
std::string s = "C+"; char ch = '+';
s.push_back(ch); s += ch; //string::operator+=, which is overloaded for chars and internally calls to the push_back() function. s.append(1, ch); //1*ch个字符 s.append("abcd"); //后面添加abcd字符串
std::stringstream ss; ss << s << ch; ss >> s;
s.insert(s.length(), 1, ch);
连接
1 2 3 4 5
//连接 string, 很简单。 str1 = str1 + str2; //连接 char * , src 和 dest 所指内存区域不可以重叠且 dest 必须有足够的空间来容纳 src 的字符串。结果返回指向 dest 的指针。 #include<cstring> strcat(dest, src);
intmain() { std::string str("This is an example sentence."); std::string str1(str); std::cout << str << '\n'; // "This is an example sentence." str.erase (10,8); // ^^^^^^^^ //去除index=10的连续8个元素,
std::string s = "C,C++,Java,"; if (!s.empty()) { s.pop_back(); }
if (!s.empty()) { s.resize(s.size() - 1); }
if (!s.empty()) { s.erase(std::prev(s.end())); }
if (!s.empty()) { s.erase(s.size() - 1); }
改
截取
1 2 3 4
// Copy three characters of s1 (starting // from position 1) //第一个参数是要截取的字符串,第二个参数是截取的开始位置,第三个参数是截取长度(可选)1。如果没有指定长度,则子字符串将延续到源字符串的结尾。 string r = s1.substr(1, 3);
1 2 3 4 5 6 7 8
// Take any string string s = "dog:cat"; // Find position of ':' using find() int pos = s.find(":"); // Copy substring after pos(include pos) string sub = s.substr(pos); // Copy substring before pos(not include pos) string sub = s.substr(0 , pos);
反转string
1
reverse(greeting.begin(),greeting.end());
查
长度
1 2 3 4
//总长度 len = str3.size(); // strlen 大部分情况结果和size一样,但是字符串里有\0, strlen会提前返回。 len = strlen(s1);
intmain(){ std::string text = "Hello, world!"; std::string prefix = "Hello";
if (hasPrefix(text, prefix)) { std::cout << "The string starts with the prefix." << std::endl; } else { std::cout << "The string does not start with the prefix." << std::endl; }
intmain(){ std::string text = "Hello, world!"; std::string prefix = "Hello";
if (hasPrefix(text, prefix)) { std::cout << "The string starts with the prefix." << std::endl; } else { std::cout << "The string does not start with the prefix." << std::endl; }
return0; }
方法 3:使用 std::string::starts_with (C++20)
如果你使用的是 C++20 或更高版本,可以直接使用 starts_with 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include<iostream> #include<string>
intmain(){ std::string text = "Hello, world!"; std::string prefix = "Hello";
if (text.starts_with(prefix)) { std::cout << "The string starts with the prefix." << std::endl; } else { std::cout << "The string does not start with the prefix." << std::endl; }
push() adds a copy of an already constructed object into the queue as a parameter.
emplace() constructs a new object in-place at the end of the queue.
If your usage pattern is one where you create a new object and add it to the container, you shortcut a few steps(creation of a temporary object and copying it) by using emplace().
//区分 //calloc() 函数是动态申请内存函数之一,相当于用malloc函数申请并且初始化一样,calloc函数会将申请的内存全部初始化为0。 int *res = (int*)calloc(numsSize, sizeof(int)); //方法二: int *res = (int*)malloc(numsSize * sizeof(int)); memset(res, 0, numsSize * sizeof(int)); //错误写法: memset(res, 0, sizeof(res)); res是指针变量,不管 res 指向什么类型的变量,sizeof( res ) 的值都是 4。
new的常见用法
1 2 3 4 5 6 7 8
int *p = newint();//此时p指向内存的单变量被初始化为0 int *p = newint (5);//此时p指向内存的单变量被初始化为5 int *p = newint[100]()//此时p指向数组首元素,且数组元素被初始化为0 //c++11 允许列表初始化,因此也有了以下几种形式形式 int *p = newint{}//p指向的单变量被初始化为0 int *p = newint{8}//p指向变量被初始化为8 int *p = newint[100]{}//p指向的数组被初始化为0 int *p = newint[100]{1,2,3}//p指向数组的前三个元素被初始化为1,2,3,后边97个元素初始化为0;
The C++ standard does not officially support Variable Length Arrays (VLA), but some compilers, such as g++ and Clang++, may accept it as valid syntax as an extension to the language.
leetcode uses g++ 5.4.0 compiler for C++ compilation. It supports variable length array definitions. After ISO C99 specification, arrays with variable length declarations are allowed.
The storage is allocated at the point of declaration and deallocated when the block scope containing the declaration exits.
Message Passing Interface (消息传递接口 MPI) is a standardized and portable message-passing standard designed to function on parallel computing architectures.[1]
The MPI standard defines the syntax 语法 and semantics 语意 of library routines that are useful to a wide range of users writing portable message-passing programs in C, C++, and Fortran.
There are several open-source MPI implementations (MPICH,Open MPI), which fostered the development of a parallel software industry, and encouraged development of portable and scalable large-scale parallel applications.
MPI hardware research focuses on implementing MPI directly in hardware, for example via processor-in-memory, building MPI operations into the microcircuitry of the RAM chips in each node. By implication, this approach is independent of language, operating system, and CPU, but cannot be readily updated or removed. MPI硬件研究的重点是直接在硬件中实现MPI,例如通过内存处理器,将MPI操作构建到每个节点中的RAM芯片的微电路中。通过暗示,这种方法独立于语言、操作系统和CPU,但是不能容易地更新或删除。
Another approach has been to add hardware acceleration to one or more parts of the operation, including hardware processing of MPI queues and using RDMA to directly transfer data between memory and the network interface controller(NIC 网卡) without CPU or OS kernel intervention. 另一种方法是将硬件加速添加到操作的一个或多个部分,包括MPI队列的硬件处理以及使用RDMA在存储器和网络接口控制器之间直接传输数据,而无需CPU或OS内核干预。
#include <unistd.h> char hostname[100]; gethostname(hostname,sizeof(hostname)); printf( "Hello world from process %d of %d: host: %s\n", rank, size, hostname);
int MPI_Pack(const void *inbuf, int incount, MPI_Datatype datatype, void *outbuf, int outsize, int *position, MPI_Comm comm) int MPI_Unpack(const void *inbuf, int insize, int *position, void *outbuf, int outcount, MPI_Datatype datatype, MPI_Comm comm)
The input value of position is the first location in the output buffer to be used for packing. position is incremented by the size of the packed message,
and the output value of position is the first location in the output buffer following the locations occupied by the packed message. The comm argument is the communicator that will be subsequently used for sending the packed message.
1 2
//Returns the upper bound on the amount of space needed to pack a message int MPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int *size)
例子: 这里的A+i*j应该写成A+i*2吧???
派生数据类型(Derived Data Type)
来定义由数据类型不同且地址空间不连续的数据项组成的消息。
1 2 3 4 5 6 7 8
//启用与弃用数据类型 int MPI_Type_commit(MPI_Datatype * datatype) int MPI_Type_free(MPI_Datatype * datatype) //相同数据类型 int MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype * newtype) //成块的相同元素组成的类型,块之间具有相同间隔 int MPI_Type_vector(int count, int blocklength, int stride, MPI_Datatype oldtype, MPI_Datatype * newtype)
1 2 3 4 5 6
//成块的相同元素组成的类型,块长度和偏移由参数指定 int MPI_Type_indexed(int count, const int *array_of_blocklengths, const int *array_of_displacements, MPI_Datatype oldtype, MPI_Datatype * newtype)
1 2 3 4 5
//由不同数据类型的元素组成的类型, 块长度和偏移(肯定也不一样)由参数指定 int MPI_Type_struct(int count, int *array_of_blocklengths, MPI_Aint * array_of_displacements, MPI_Datatype * array_of_types, MPI_Datatype * newtype)
// Makes a new communicator to which topology拓扑 information has been attached int MPI_Cart_create( MPI_Comm old_comm,//旧的通信域。这个通讯域中的所有进程都要调用该函数 int dims,//网格维数 number of dimensions of cartesian grid (integer) int* size,//长度为dims的数组,size[j]是第j维的进程数, integer array of size ndims specifying the number of processes in each dimension int* periodic,//长度为dims的数组,如果第j维有周期性,那么periodic[j]=1,否则为0 int reorder,//进程是否能重新被编号,如果为0则进程在新的通信域中仍保留在旧通信域的标号 MPI_Comm* cart_comm//该函数返回后,此变量将指向新的笛卡尔通信域 );
int MPI_Cart_rank(MPI_Comm comm, const int coords[], int *rank) //Determines process rank in communicator given Cartesian location //该函数的作用是通过进程在网格中的坐标获得它的进程号
int MPI_Cart_coords(MPI_Comm comm, int rank, int maxdims, int coords[]) //Determines process coords in cartesian topology given rank in group //该函数的作用是确定某个线程在虚拟网格中的坐标
通信域划分
1 2 3 4 5 6
int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm) //Creates a new communicator
int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm * newcomm) 将某个通信域进一步划分为几组
组间通信域
点对点通信
特殊的函数
1 2 3 4 5 6 7
int MPI_Sendrecv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status * status) int MPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype, int dest, int sendtag, int source, int recvtag, MPI_Comm comm, MPI_Status * status)
特别适用于在进程链(环)中进行“移位”操作,而避免在通讯为阻塞方式时出现死锁。
There is also another error. The MPI standard requires that the send and the receive buffers be disjoint不相交 (i.e. they should not overlap重叠), which is not the case with your code. Your send and receive buffers not only overlap but they are one and the same buffer. If you want to perform the swap in the same buffer, MPI provides the MPI_Sendrecv_replace operation.
const double a = 0.0; const double b = 3.1415926; int n = 100; double h = (b - a) / n;
double trap(double a, double b, int n, double h) { double*x = new double[n + 1]; double*f = new double[n + 1]; double inte = (sin(a) + sin(b)) / 2; for (int i = 1; i<n + 1; i++) { x[i] = x[i - 1] + h; /*x_0=a,x_n=b*/ f[i] = sin(x[i]); inte += f[i]; } inte = inte*h; /* inte=h*[f(a)/2+f(x_1)+...f(x_{n-1})+f(b)/2]*/ return inte; }
int main(int argc, char * argv[]) { int myid, nprocs; int local_n; double local_a; double local_b; double total_inte;
MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myid); /* get current process id */ MPI_Comm_size(MPI_COMM_WORLD, &nprocs); /* get number of processes */