繁体   English   中英

cpp中的并行memcpy

Parallel memcpy in cpp

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我正在尝试并行复制矩阵。 下面是我正在使用的代码。 目前,它可以与char一起正常工作,但是当我使用短裤时它会出现段错误。 我认为错误在于复制向量之外的内存。 我试图调试我的假设,但没有成功。

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(memcpy CXX)
find_package (Threads)
add_executable(memcpy main.cpp)
set_property(TARGET memcpy PROPERTY CXX_STANDARD 17)
target_link_libraries (memcpy ${CMAKE_THREAD_LIBS_INIT})

main.cpp

#include <cassert>
#include <condition_variable>
#include <cstring>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
#include <vector>


class Barrier {
  public:
    explicit Barrier(std::size_t const count) : m_threshold(count), m_remaining(count), m_generation(0) {}

    void wait() {
        auto local = std::unique_lock<std::mutex>{m_mutex};
        auto current_generation = m_generation;

        m_remaining--;
        if (!m_remaining) {
            m_generation++;
            m_remaining = m_threshold;
            m_condition.notify_all();
        } else {
            m_condition.wait(local, [this, current_generation] { return current_generation != m_generation; });
        }
    }

  private:
    std::mutex m_mutex;
    std::condition_variable m_condition;
    std::size_t m_threshold;
    std::size_t m_remaining;
    std::size_t m_generation;
};


template <typename T>
class Matrix {
    using reference = typename std::vector<T>::reference;
    using const_reference = typename std::vector<T>::const_reference;

  public:
    Matrix(std::size_t rows, std::size_t cols) : m_rows(rows), m_cols(cols), m_data(m_cols * m_rows) {}
    Matrix(std::size_t rows, std::size_t cols, T const& default_val) : m_rows(rows), m_cols(cols), m_data(m_cols * m_rows, default_val) {}

    constexpr std::size_t get_columns() const { return m_cols; }
    constexpr std::size_t get_rows() const { return m_rows; }
    constexpr std::size_t get_element_count() const {
        assert(m_cols * m_rows == m_data.size());
        return m_cols * m_rows;
    }

    T* data() { return m_data.data(); }
    T const* data() const { return m_data.data(); }

    reference operator()(std::size_t const column_x, std::size_t const row_y) {
        assert(0 <= column_x);
        assert(column_x < get_columns());
        assert(0 <= row_y);
        assert(row_y < get_rows());

        return m_data[row_y * m_cols + column_x];
    }

    const_reference operator()(std::size_t const column_x, std::size_t const row_y) const {
        assert(0 <= column_x);
        assert(column_x < get_columns());
        assert(0 <= row_y);
        assert(row_y < get_rows());

        return m_data[row_y * m_cols + column_x];
    }

  private:
    std::size_t const m_rows;
    std::size_t const m_cols;
    std::vector<T> m_data;
};


static_assert(false, "FIX ME");
using T = char;
// using T = short;
// using T = int;
// using T = double;


void run(std::size_t const my_rank, std::size_t const num_threads, Barrier& barrier, Matrix<T> const& from_data, Matrix<T>& to_data) {
    auto n = from_data.get_element_count();
    std::string str;

    if (my_rank == 0) {
        std::cerr << "bytes to copy: " << (n * sizeof(T)) << '\n';
    }

    // initialization
    std::size_t segment_size = n / num_threads;
    std::size_t start = (my_rank * segment_size) * sizeof(T);
    std::size_t end = ((my_rank + 1) * segment_size) * sizeof(T);
    std::size_t distance = end - start;


    str += "  my_rank: " + std::to_string(my_rank);
    str += "  segment_size: " + std::to_string(segment_size);
    str += "  start: " + std::to_string(start);
    str += "  end: " + std::to_string(end);
    str += "  distance: " + std::to_string(distance);
    str += "  rank: " + std::to_string(my_rank);
    str += "  start: " + std::to_string(start);
    str += "  end: " + std::to_string(end);
    str += "  distance: " + std::to_string(distance);
    str += "  e: " + std::to_string(start + distance);
    str += "\n";
    std::cerr << str;

    barrier.wait();
    std::memcpy(to_data.data() + start, from_data.data() + start, distance);
    barrier.wait();


    if (my_rank == 0)
        for (auto y = 0; y < from_data.get_rows(); y++) {
            for (auto x = 0; x < from_data.get_columns(); x++) {
                if (to_data(x, y) != from_data(x, y)) {
                    std::cerr << "x: " << x << '\t' << "y: " << y << "\t\t";
                    std::cerr << "to: " << to_data(x, y) << '\t' << "from: " << from_data(x, y) << '\n';
                }
            }
        }

    barrier.wait();
}


int main() {
    auto const num_threads = 1;
    // auto const num_threads = 4;

    // auto const width = 64;
    // auto const height = 64;
    auto const width = 97;
    auto const height = 101;

    auto from_data = Matrix<T>(width, height, 70);
    auto to_data = Matrix<T>(width, height, 84);

    std::vector<std::thread> threads;
    auto barrier = Barrier{num_threads};
    for (auto i = 0; i < num_threads; i++) {
        threads.emplace_back(run, i, num_threads, std::ref(barrier), std::ref(from_data), std::ref(to_data));
    }

    for (auto& thread : threads) {
        thread.join();
    }
}
1 个回复

std::memcpy(to_data.data() + start, from_data.data() + start, distance)

std::vector<T>::data()返回T*因此,如果向其添加整数值foo ,则可以有效地添加foo * sizeof T字节...但是在计算时,您早已与sizeof(T)相乘startend 另外, std::memcpy()不适用于不是POD的T

最好使用std::copy()

1 cpp中的并行openMP循环

我正在尝试使用cpp中的openMP进行并行化。 我正在使用以下测试示例 我正在使用4个线程; 顶部(在Unix中),然后应该在col%CPU 400%或类似的名称中看到。 但是我得到100%的串行执行情况。 而且,如果我测量时间,则与串行执行相比没有速度增益。 我不知道我在做 ...

2 R中的并行cpp函数?

所以我有2个自定义Rcpp函数CustFunc1(x,y)和CustFunc2(a,b) 。 两者都对计算有要求(因此是c ++)。 我的问题是R中是否可以与dopar包同时运行? 还是可以进行系统调用以直接访问cpp代码并尝试通过某些命令行工具并行执行? 现在的流程是: ...

3 cpp中std :: vector的并行排序

概述 我正在编写用于在多线程中对std::vector&lt;std::string&gt;进行排序的代码。 所以我使用了 mergeSort 的概念,我将向量分成块并对块进行排序,然后将其合并。 所有的排序和合并都是在基本向量上完成的。 过程中没有完成任务 我并行排序,排序完成后,我并行合并向量。 ...

4 在cpp中为并行循环生成随机数

我编写了使用并行计算的代码。 因为将随机数添加到并行循环比较棘手,所以我尝试通过在并行循环之前生成随机数来生成独立的随机数。 但是,我仍然不确定这是否完全正确或可能导致其他问题。 如果您能帮助我,我将不胜感激。 与上面的讨论相关的代码部分是: 重要说明:在UpdateNode函数中,我对数组( ...

7 C中的memcpy函数

为什么下面的代码会导致分段错误? 我为“ s”分配了8000bytes。 并且仅将“ t”复制到s直到7000bytes。 尽管我为s分配了8000个字节,但为什么会出现分段错误呢? ...

2012-01-02 18:13:35 4 2600   c/ linux
8 memcpy中的数据损坏

我目前正在通过WinSock使用套接字的项目,遇到一个特殊的问题。 在开始解释之前,我将附加代码。 和协议 本质上,协议保留了客户端和服务器相互抛出的消息的定义。 我遇到的问题是,在connection.cpp第132行(memcpy)中,消息在sendBuf中变成乱码。 ...

9 为什么导入表中没有memcpy?

当我在符号列表中看到memcpy时,我正在使用Visual Studio生成的pdb,因此我使用dumpbin检查可执行文件中的import表,但是那里没有对memcpy引用。 memcpy是不是从crt库导出的函数? 如果是这样,为什么我不在dumpbin的输出中看到它? ...

10 Memcpy 实现中的优化

下面是我在搜索优化的memcpy实现时得到的代码。 这是链接 有人可以向我解释下面的行吗? 在这里,他们想检查src和dst地址是否与4 byte边界对齐。 他们为什么使用! 但是,因为它每次都会使条件为false ? 其次,上面的代码是否还有进一步优化的余地? ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM