std::threadを何とか使う。

 

とりあえず動いた。配列はvectorに置換して。
#include <iostream>
#include <thread>
#include <vector>
#include <string>
#include "clMatrix.hpp"

template<typename T>
void fcShow(T data) {std::cout << data ;}
template<typename T, typename K>
void fcThreadWork_xxx(T& tA, T& tB,int iSf,int iEf) {
    for(int i=iSf;i<iEf;++i){
        K tmp;
        tmp = tA(i);
        tA(i) = tB(i);
        tB(i) = tmp;
        //std::swap(tA(i),tB(i));
    }
}
template<typename T>
void fcDump(string str,T& tX) {
    fcShow(str);
    int iSize = tX.fcGetSize();
    for (int i = 0; i < iSize; ++i) {
        fcShow(tX(i));
        fcShow(",");
    }
    fcShow("\n");
}
int main()
{
    int hoge = 100;
    const int iSize = hoge;

    mtd::clVector<double>dA(iSize); mtd::clVector<double>dB(iSize);
    for (int i = 0; i < iSize; ++i) {dA(i) = i;dB(i) = i * -10;}
    fcShow("■ ■ ■ ナイーブに交換 前 ■ ■ ■\n");
    fcDump("dA:",dA); fcDump("dB:", dB);
    const double dThreadNumRatio = 0.5;
    int iThreadNum = (int)((double)std::thread::hardware_concurrency() * dThreadNumRatio);
    if (iThreadNum == 0) { iThreadNum = 2; }
    int iStep = (int)((double)iSize / (double)iThreadNum);

    std::vector<std::thread> obThreads(iThreadNum);
    // スレッドを生成
    for (int i = 0; i < iThreadNum; ++i) {
        int iS = 0, iE = 0;
        iS = i * iStep;
        if (i < iThreadNum -1) {
            iE = iS + iStep;
        } else {
            iE = iSize;
        }
        obThreads[i] = (std::thread(fcThreadWork_xxx<mtd::clVector<double>,double>, std::ref(dA), std::ref(dB), iS, iE));
        //threads.push_back(std::thread(fcSwapThWork, std::ref(dA), std::ref(dB), iS, iE));
    }

        // 各スレッドの終了を待つ
        for (auto& t : obThreads) {
            t.join();
        }
    
        fcShow("■ ■ ■ ナイーブに交換 後 ■ ■ ■\n");
        fcDump("dA:", dA); fcDump("dB:", dB);
        std::cout << "Hello World!\n";
}

 

引用 google で std::thread を検索。そのウェブページ

アライメントのそろった動的配列

 

ここへ書く

 

引用 ChatGPT

PS:GCC用みたい。CPUに対して余計な事するかもしれない。

 

プリフェッチは「次にアクセスするメモリ」を予告しておく行為。

i+1 は処理が1周回ってから本当に使われるので、キャッシュが効く余地がある!
期待はせずに、自分の車を魔改造する程度で。
 

//プリフェッチ // fcPreFetchUp (i+1 < pCol を守る)
// 上向きカウント専用
inline void fcPreFetchUp(const size_t& i) noexcept {
    #if defined(PREFETCH_OPT)
        if (i + 1 < pCol) {
            //if (i + 1 < pCol) って遅い?いいえ、ほぼ無視できるオーバーヘッドです。現代CPUと最適化コンパイラ(特に -O2 以上)では、if (i + 1 < N)は分岐予測が効いてほぼノーコスト。
            __builtin_prefetch(&mVector[i + 1], 0, 1);
        }
    #endif
}

// 下向きカウント専用(最後から2つ前まで)
inline void fcPreFetchDown(const size_t& i) noexcept {
    #if defined(PREFETCH_OPT)
        if (i >= 1) {
            __builtin_prefetch(&mVector[i - 1], 0, 1);
        }
    #endif
}

//とある関数内
for (size_t i = 0; i < piSize; ++i) {
    fcPreFetchUp(i);
    mVector[i]=i;
}

 

引用ChatGPT

C++のマクロ

 

から引用。

 

#define REP(i, n) for (int i = 0; (i) < (n); ++i)
#define REPD(i, n) for (int i = (n)-1; (i) >= 0; --i)      // 逆ループ
#define FOR(i, a, b) for (int i = (a); (i) < (b); ++i)     // 任意範囲
#define ALL(a) (a), (a) + sizeof(a)/sizeof((a)[0])         // 範囲(配列用)

 

 

//段階的デバッグ切り替え
#define DEBUG_LEVEL 1  // ← ← ← ここを切り替えるだけ!
#if DEBUG_LEVEL >= 1
#define DBG1(x) x
#else
#define DBG1(x)
#endif

#if DEBUG_LEVEL >= 2
#define DBG2(x) x
#else
#define DBG2(x)
#endif

使用例
DBG1(std::cout << "簡易デバッグ\n";)
DBG2(std::cout << "詳細デバッグ\n";)
//DEBUG_LEVEL 0 → どちらも出ない(完全無視)
//DEBUG_LEVEL 1 → DBG1 だけ出る(一部有効)
//DEBUG_LEVEL 2 → 両方出る(フルデバッグ)

 

複数行はどうかな?

 

int main() { 

DBG(

 

 std::cout << "debug\n"; std::cout << "debug\n"; std::cout << "debug\n"; std::cout << "debug\n"; std::cout << "debug\n"; std::cout << "debug\n"; std::cout << "debug\n";

 

)

 std::cout << "Hello World!\n";

}// いけた。

 

引用 chatGPT