#include <iostream>
using namespace std;
const int BUFSIZE = 1 << 20;
char padded_buffer[64 + BUFSIZE + 64];
char* buffer = padded_buffer + 64;
int main()
{
buffer[-1] = '?';
// is that always equivalent to padded_buffer[63] = '?' ?
cout << padded_buffer[63] << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我有一段像上面这样的代码。基本上,由于某些原因,我需要“隔离”阵列的两侧。
但我想知道上面的语法是否安全?我知道负索引通常是未定义的行为,但是这种情况又如何呢?
// spinlockAcquireRelease.cpp
#include <atomic>
#include <thread>
class Spinlock{
std::atomic_flag flag;
public:
Spinlock(): flag(ATOMIC_FLAG_INIT) {}
void lock(){
while(flag.test_and_set(std::memory_order_acquire) ); // line 12
}
void unlock(){
flag.clear(std::memory_order_release);
}
};
Spinlock spin;
void workOnResource(){
spin.lock();
// shared resource
spin.unlock();
}
int main(){
std::thread t(workOnResource);
std::thread t2(workOnResource);
t.join();
t2.join();
}
Run Code Online (Sandbox Code Playgroud)
注释中说:
如果两个以上的线程使用自旋锁,则 lock 方法的获取语义是不够的。现在lock方法是一个获取-释放操作。因此第 12 行 [对 的调用] 中的内存模型
flag.test_and_set(std::memory_order_acquire)必须更改为std::memory_order_acq_rel。
为什么这个自旋锁适用于 2 个线程,但不适用于超过 2 个线程?导致此自旋锁出错的示例代码是什么?
来源: https: //www.modernnescpp.com/index.php/acquire-release-semantic
我正在使用 godbolt 来组装以下程序:
\n#include <stdio.h>\nvolatile int a = 5;\nvolatile int res = 0;\nint main() {\n res = a * 36;\n return 1;\n}\nRun Code Online (Sandbox Code Playgroud)\n如果我使用-Os优化,生成的代码很自然:
\nmov eax, DWORD PTR a[rip]\nimul eax, eax, 36\nmov DWORD PTR res[rip], eax\nRun Code Online (Sandbox Code Playgroud)\n但如果我使用-O2,生成的代码是这样的:
\nmov eax, DWORD PTR a[rip]\nlea eax, [rax+rax*8]\nsal eax, 2\nmov DWORD PTR res[rip], eax\nRun Code Online (Sandbox Code Playgroud)\n因此,它不是乘以 5*36,而是执行 5 -> 5+5*8=45 -> 45*4 = 180。我认为这是因为 1 imul 比 1 lea + 1 左移慢。
\n但在 lea 指令中,需要计算rax+rax*8,其中包含 1 个加法 …
#include <stdio.h>
#include <iostream>
#include <string>
#include <chrono>
#include <memory>
#include <cstdlib>
#include <cstdint>
#include <cstring>
#include <immintrin.h>
using namespace std;
const int p[9] = {1, 10, 100,
1000, 10000, 100000,
1000000, 10000000, 100000000};
class MyTimer {
private:
std::chrono::time_point<std::chrono::steady_clock> starter;
public:
void startCounter() {
starter = std::chrono::steady_clock::now();
}
int64_t getCounterNs() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - starter).count();
}
};
int convert1(const char *a) {
int res = 0;
for (int i=0; i<9; i++) res = res * 10 + a[i] - 48; …Run Code Online (Sandbox Code Playgroud) #include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream fo("output/folder1/data/today/log.txt");
fo << "Hello world\n";
fo.close();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我需要将一些日志数据输出到一些具有变量名称的文件中。但是,ofstream不会一路创建目录,如果文件的路径不存在,则不会ofstream写入任何地方!
如何沿着文件路径自动创建文件夹?系统只有Ubuntu。
或者如果我想确保数组包含全0,我是否需要执行cudaMemset()?我在文档中找不到它。谢谢。
int n_attrs = some_input_from_other_function() // [2..5000]
vector<int> corr_indexes; // size = n_attrs * n_attrs
vector<char> selected; // szie = n_attrs
vector<pair<int,int>> selectedPairs; // size = n_attrs / 2
// vector::reserve everything here
...
// optimize the code below
const int npairs = n_attrs * n_attrs;
selectedPairs.clear();
for (int i = 0; i < npairs; i++) {
const int x = corr_indexes[i] / n_attrs;
const int y = corr_indexes[i] % n_attrs;
if (selected[x] || selected[y]) continue; // fit inside L1 cache …Run Code Online (Sandbox Code Playgroud) uint8_t data[] = "mykeyxyz:1234\nky:123\n...";。我的字符串行有 format key:value,其中每一行都有len(key) <= 16保证。我想加载mykeyxyz到 a 中__m128i,但将较高的位置填为 0。
最简单的方法是使用 255 或 0 掩码的数组,但这需要另一个内存负载。有没有办法更快地做到这一点?
接受的答案使总程序时间加快了约 2%。要进行比较,请进行测试1brc_valid13.cpp(1brc_valid14.cpp使用已接受的答案)。硬件:AMD 2950X、Ubuntu 18.04、g++ 11.4,编译命令:g++ -o main 1brc_final_valid.cpp -O3 -std=c++17 -march=native -m64 -lpthread
编辑:最好没有 AVX512
编辑 2:我需要变量,len以便我可以开始解析值部分。
编辑 3:该函数将在循环中使用(例如解析 100 万行文本)。但strcmp_mask基本上总是在 L1 缓存内
编辑 4:我通过解析 10 亿行(key,value)并处理它们来对函数进行基准测试。您可以下载代码/数据并在我的存储库中复制结果: https: //github.com/lehuyduc/1brc-simd。此外,讨论帖将包含更多信息
编辑 5:我测试maskafterc256发现它导致我的代码慢了 50 倍!如果我替换_mm256_set_epi8为 …
#include <iostream>
#include <chrono>
using namespace std;
class MyTimer {
private:
std::chrono::time_point<std::chrono::steady_clock> starter;
std::chrono::time_point<std::chrono::steady_clock> ender;
public:
void startCounter() {
starter = std::chrono::steady_clock::now();
}
double getCounter() {
ender = std::chrono::steady_clock::now();
return double(std::chrono::duration_cast<std::chrono::nanoseconds>(ender - starter).count()) /
1000000; // millisecond output
}
// timer need to have nanosecond precision
int64_t getCounterNs() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now() - starter).count();
}
};
MyTimer timer1, timer2, timerMain;
volatile int64_t dummy = 0, res1 = 0, res2 = 0;
// time run without any time measure
void func0() { …Run Code Online (Sandbox Code Playgroud) #include <iostream>
#include <any>
#include <string>
#include <vector>
#include <map>
using namespace std;
string AnyPrint(const std::any &value)
{
cout << size_t(&value) << ", " << value.type().name() << " ";
if (auto x = std::any_cast<int>(&value)) {
return "int(" + std::to_string(*x) + ")";
}
if (auto x = std::any_cast<float>(&value)) {
return "float(" + std::to_string(*x) + ")";
}
if (auto x = std::any_cast<double>(&value)) {
return "double(" + std::to_string(*x) + ")";
}
if (auto x = std::any_cast<string>(&value)) {
return "string(\"" + (*x) + "\")"; …Run Code Online (Sandbox Code Playgroud) struct Heap {
int capacity;
int heapSize;
int *tree; // the heap binary tree
int *pos; // pos[i] is the position of values[i] in items
float *p; // priority value of each heap element
};
void initHeap(struct Heap *heap, int capacity) {
heap->capacity = capacity;
heap->heapSize = 0;
heap->tree = malloc(sizeof(int)*(capacity+1));
heap->pos = malloc(sizeof(int)*(capacity+1));
heap->p = malloc(sizeof(float)*(capacity+1));
}
void betterInit(struct Heap *heap, int capacity) {
with (heap) { // doesn't exist
capacity = capacity;
heapSize = 0;
tree = malloc(sizeof(int)*(capacity+1)); …Run Code Online (Sandbox Code Playgroud) c++ ×9
optimization ×5
assembly ×3
c ×3
cuda ×2
string ×2
x86-64 ×2
arrays ×1
atomic ×1
avx ×1
c-strings ×1
file ×1
filepath ×1
filesystems ×1
indexing ×1
linux ×1
malloc ×1
math ×1
memset ×1
mutex ×1
performance ×1
pointers ×1
rtti ×1
simd ×1
spinlock ×1
sse ×1
stdany ×1
struct ×1
time ×1
ubuntu ×1