mardi 29 août 2023

How to use pwrite to write files in parallel on Linux by C++?

I'm tring to create several threads to write some data chunks into one file in parallel. Some part of my code is below:

void write_thread(float* data, size_t start, size_t end, size_t thread_idx) {
    auto function_start_time = std::chrono::high_resolution_clock::now();
    auto start_duration = std::chrono::duration_cast<std::chrono::milliseconds>(function_start_time - global_start_time).count();

    std::cout << "Thread " << thread_idx << " started after " << start_duration << " ms from global start time." << std::endl;

    pwrite(fd, data + start, (end - start) * sizeof(float), start * sizeof(float));
    close(fd);

    auto function_end_time = std::chrono::high_resolution_clock::now();
    auto end_duration = std::chrono::duration_cast<std::chrono::milliseconds>(function_end_time - global_start_time).count();

    std::cout << "Thread " << thread_idx << " ended after " << end_duration << " ms from global start time." << std::endl;

    thread_durations[thread_idx] = std::chrono::duration_cast<std::chrono::milliseconds>(function_end_time - function_start_time);

int main() {
    fd = open(FILENAME, O_RDWR | O_CREAT, 0666);
    if (fd < 0) {
        perror("Failed to open file");
        return 1;
    }
    float* data = new float[FLOATS_COUNT];
    for (size_t i = 0; i < FLOATS_COUNT; i++) {
        data[i] = static_cast<float>(i);
    }

    auto globalStartTime = std::chrono::high_resolution_clock::now();

    std::vector<std::thread> write_threads;
    size_t floats_per_thread = FLOATS_COUNT / THREADS_COUNT;
    for (size_t t = 0; t < THREADS_COUNT; t++) {
        size_t start = t * floats_per_thread;
        size_t end = (t == THREADS_COUNT - 1) ? FLOATS_COUNT : start + floats_per_thread;
        write_threads.emplace_back(write_thread, data, start, end, t);
    }
    for (auto& t : write_threads) {
        t.join();
    }
    ....
}

On my Ubuntu server, I create some data chunks and create the same numbers threads to write these chunks into one file. However, by printing the function which threads excutes, I find that all threads start at the same time, but the threads are ending one by one, each at the same interval. So I think it's sequential execution.

However, when I run the same code on my MACOS, I find that all threads end at the same time!(interval less than 2ms)

I'm wondering what was happended on my Ubuntu server? What's casuing this difference and how to deal with it?

Thanks!

Aucun commentaire:

Enregistrer un commentaire