Saya tidak mengerti di mana saya memiliki masalah dalam kode menggunakan sse

Saya baru dengan pemrograman sse. Saya ingin menulis kode di mana saya menjumlahkan 4 bilangan berurutan dari vektor v dan menulis hasil penjumlahannya dalam vektor ans. Saya ingin menulis kode yang dioptimalkan menggunakan sse. Tetapi ketika saya mengatur ukurannya sama dengan 4, program saya berfungsi. Tetapi ketika saya mengatur ukuran 8, program saya tidak berfungsi dan saya mendapat pesan kesalahan ini: "Pengecualian dilemparkan: pelanggaran akses baca.

jawabannya adalah 0x1110112.

Jika ada pengendali untuk pengecualian ini, program dapat dilanjutkan dengan aman." Saya tidak mengerti di mana saya mempunyai masalah. Saya mengalokasikan memori dengan benar, di tempat mana saya mempunyai masalah. Adakah yang bisa membantu saya, saya akan membantu sangat bersyukur.

#include <iostream>
#include <immintrin.h>
#include <pmmintrin.h>
#include <vector>
#include <math.h>  
using namespace std;
arith_t = double
void init(arith_t *&v, size_t size) {
    for (int i = 0; i < size; ++i) {
        v[i] = i / 10.0;
    }
}
//accumulate with sse
void sub_func_sse(arith_t *v, size_t size, int start_idx, arith_t *ans, size_t start_idx_ans) {
    __m128d first_part = _mm_loadu_pd(v + start_idx);
    __m128d second_part = _mm_loadu_pd(v + start_idx + 2);

    __m128d sum = _mm_add_pd(first_part, second_part);
    sum = _mm_hadd_pd(sum, sum);
    _mm_store_pd(ans + start_idx_ans, sum);
}
int main() {
    const size_t size = 8;
    arith_t *v = new arith_t[size];
    arith_t *ans_sse = new arith_t[size / 4];
    init(v, size);
    init(ans_sse, size / 4);
    int num_repeat = 1;
    arith_t total_time_sse = 0;
    for (int p = 0; p < num_repeat; ++p) {
        for (int idx = 0, ans_idx = 0; idx < size; idx += 4, ans_idx++) {
            sub_func_sse(v, size, idx, ans_sse, ans_idx);
        }
    }

    for (size_t i = 0; i < size / 4; ++i) {
        cout << *(ans_sse + i) << endl;
    }
    delete[] ans_sse;
    delete[] v;
}

person NN_05    schedule 30.12.2019    source sumber
comment
_mm_store_pd memerlukan penyelarasan 16-byte, yang new tidak menjamin (terutama dalam mode 32-bit pada kompiler di mana alignof(max_align_t) = 8)   -  person Peter Cordes    schedule 30.12.2019
comment
Bagaimana cara memperbaikinya? Bagaimana cara mengalokasikan memori baru dengan 16-align?   -  person NN_05    schedule 30.12.2019
comment
Meskipun bukan solusi umum yang baik, jika Anda memerlukan memori yang selaras untuk digunakan dalam _mm_intrinsics, Anda dapat menggunakan _mm_alloc dan teman-teman yang merupakan kasus penggunaan Anda.   -  person Mike Vine    schedule 30.12.2019


Jawaban (1)


Anda menggunakan memori yang tidak selaras yang memerlukan versi khusus dari fungsi muat dan penyimpanan. Anda menggunakan _mm_loadu_pd dengan benar tetapi_mm_store_pd tidak sesuai untuk bekerja dengan memori yang tidak selaras sehingga Anda harus mengubahnya ke _mm_storeu_pd. Pertimbangkan juga untuk menggunakan memori yang selaras yang akan menghasilkan kinerja lebih baik.

person navyblue    schedule 30.12.2019